tidying
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 26 Jul 2016 18:44:08 +0000 (19:44 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 2 Aug 2016 15:46:31 +0000 (16:46 +0100)
12 files changed:
src/src/deliver.c
src/src/functions.h
src/src/queue.c
src/src/structs.h
src/src/transport.c
src/src/transports/appendfile.c
src/src/transports/autoreply.c
src/src/transports/lmtp.c
src/src/transports/pipe.c
src/src/transports/smtp.c
src/src/verify.c
test/stderr/0393

index 450b58098e8f03f2a3d50d0f8d3531c5eb12325b..81f9a9aa28866895fb1d21e6da360e98722fa397 100644 (file)
@@ -6906,8 +6906,8 @@ if (addr_senddsn)
     {
     FILE *f = fdopen(fd, "wb");
     /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
-    int topt = topt_add_return_path | topt_no_body;
     uschar * bound;
+    transport_ctx tctx;
 
     DEBUG(D_deliver)
       debug_printf("sending error message to: %s\n", sender_address);
@@ -6986,7 +6986,10 @@ if (addr_senddsn)
     return_path = sender_address;   /* In case not previously set */
 
     /* Write the original email out */
-    transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
+
+    bzero(&tctx, sizeof(tctx));
+    tctx.options = topt_add_return_path | topt_no_body;
+    transport_write_message(fileno(f), &tctx, 0);
     fflush(f);
 
     fprintf(f,"\n--%s--\n", bound);
@@ -7441,8 +7444,18 @@ wording. */
       fflush(f);
       transport_filter_argv = NULL;   /* Just in case */
       return_path = sender_address;   /* In case not previously set */
-      transport_write_message(NULL, fileno(f), topt,
-        0, dsnnotifyhdr, NULL, NULL, NULL, NULL, 0);
+       {                             /* Dummy transport for headers add */
+       transport_ctx * tctx =
+         store_get(sizeof(*tctx) + sizeof(transport_instance));
+       transport_instance * tb = (transport_instance *)(tctx+1);
+
+       bzero(tctx, sizeof(*tctx)+sizeof(*tb));
+       tctx->tblock = tb;
+       tctx->options = topt;
+       tb->add_headers = dsnnotifyhdr;
+
+       transport_write_message(fileno(f), tctx, 0);
+       }
       fflush(f);
 
       /* we never add the final text. close the file */
@@ -7758,7 +7771,9 @@ else if (addr_defer != (address_item *)(+1))
         FILE *wmf = NULL;
         FILE *f = fdopen(fd, "wb");
        uschar * bound;
-        int topt;
+       transport_ctx tctx;
+
+       bzero(&tctx, sizeof(tctx));
 
         if (warn_message_file)
           if (!(wmf = Ufopen(warn_message_file, "rb")))
@@ -7905,11 +7920,12 @@ else if (addr_defer != (address_item *)(+1))
 
         fflush(f);
         /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
-        topt = topt_add_return_path | topt_no_body;
+        tctx.options = topt_add_return_path | topt_no_body;
         transport_filter_argv = NULL;   /* Just in case */
         return_path = sender_address;   /* In case not previously set */
+
         /* Write the original email out */
-        transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
+        transport_write_message(fileno(f), &tctx, 0);
         fflush(f);
 
         fprintf(f,"\n--%s--\n", bound);
index 085ed5af7cb5817401557b0cae67da3f9f34e485..27e9ff821fdf725b4c2849d45d83a623b44b6095 100644 (file)
@@ -145,9 +145,8 @@ extern uschar *deliver_get_sender_address (uschar *id);
 
 extern BOOL    directory_make(const uschar *, const uschar *, int, BOOL);
 #ifndef DISABLE_DKIM
-extern BOOL    dkim_transport_write_message(address_item *, int, int,
-                   uschar *, uschar *, uschar *, uschar *, rewrite_rule *,
-                   int, struct ob_dkim *);
+extern BOOL    dkim_transport_write_message(int, transport_ctx *,
+                 struct ob_dkim *);
 #endif
 extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
 extern int     dns_basic_lookup(dns_answer *, const uschar *, int);
@@ -469,10 +468,10 @@ extern BOOL    transport_set_up_command(const uschar ***, uschar *,
 extern void    transport_update_waiting(host_item *, uschar *);
 extern BOOL    transport_write_block(int, uschar *, int);
 extern BOOL    transport_write_string(int, const char *, ...);
-extern BOOL    transport_headers_send(address_item *, int, uschar *, uschar *,
-                 BOOL (*)(int, uschar *, int, unsigned), BOOL, rewrite_rule *, int);
-extern BOOL    transport_write_message(address_item *, int, int, int, uschar *,
-                 uschar *, uschar *, uschar *, rewrite_rule *, int);
+extern BOOL    transport_headers_send(address_item *, int, transport_instance *,
+                 BOOL (*)(int, uschar *, int, unsigned),
+                BOOL);
+extern BOOL    transport_write_message(int, transport_ctx *, int);
 extern void    tree_add_duplicate(uschar *, address_item *);
 extern void    tree_add_nonrecipient(uschar *);
 extern void    tree_add_unusable(host_item *);
index 1b7b9f74c51e9f8d7eedfdf871b8d8cb496dbca1..7648f47ca4b2bc223bc3f482072341ce22956e1f 100644 (file)
@@ -1145,7 +1145,7 @@ switch(action)
   case MSG_SHOW_COPY:
   deliver_in_buffer = store_malloc(DELIVER_IN_BUFFER_SIZE);
   deliver_out_buffer = store_malloc(DELIVER_OUT_BUFFER_SIZE);
-  transport_write_message(NULL, 1, 0, 0, NULL, NULL, NULL, NULL, NULL, 0);
+  transport_write_message(1, NULL, 0);
   break;
 
 
index b49f4b574c4ca1ec5bd8bdd4a5b5d35f5853e0dd..61f8a4169446ed165e9c8128d42067940f0a66b4 100644 (file)
@@ -223,6 +223,17 @@ typedef struct transport_info {
 } transport_info;
 
 
+/* Structure for information about a delivery-in-progress */
+
+typedef struct transport_context {
+  transport_instance * tblock;
+  struct address_item * addr;
+  uschar       * check_string;
+  uschar       * escape_string;
+  int            options;              /* topt_* */
+} transport_ctx;
+
+
 
 typedef struct {
   uschar *request;
index dfe1d7782da3ad957c327c6dcef95a95d7d80b60..148c1955f7c045e26682bd213cc7d7fb75ce68f3 100644 (file)
@@ -623,12 +623,12 @@ Arguments:
 Returns:                TRUE on success; FALSE on failure.
 */
 BOOL
-transport_headers_send(address_item *addr, int fd, uschar *add_headers, uschar *remove_headers,
+transport_headers_send(address_item *addr, int fd, transport_instance * tblock,
   BOOL (*sendfn)(int fd, uschar * s, int len, unsigned options),
-  BOOL use_crlf, rewrite_rule *rewrite_rules, int rewrite_existflags)
+  BOOL use_crlf)
 {
 header_line *h;
-unsigned wck_flags = use_crlf ? topt_use_bdat : 0;
+const uschar *list;
 
 /* Then the message's headers. Don't write any that are flagged as "old";
 that means they were rewritten, or are a record of envelope rewriting, or
@@ -640,10 +640,9 @@ Then check addr->prop.remove_headers too, provided that addr is not NULL. */
 for (h = header_list; h; h = h->next) if (h->type != htype_old)
   {
   int i;
-  const uschar *list = remove_headers;
-
   BOOL include_header = TRUE;
 
+  list = tblock ? tblock->remove_headers : NULL;
   for (i = 0; i < 2; i++)    /* For remove_headers && addr->prop.remove_headers */
     {
     if (list)
@@ -666,9 +665,9 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old)
        while (*ss == ' ' || *ss == '\t') ss++;
        if (*ss == ':') break;
        }
-      if (s != NULL) { include_header = FALSE; break; }
+      if (s) { include_header = FALSE; break; }
       }
-    if (addr != NULL) list = addr->prop.remove_headers;
+    if (addr) list = addr->prop.remove_headers;
     }
 
   /* If this header is to be output, try to rewrite it if there are rewriting
@@ -676,14 +675,15 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old)
 
   if (include_header)
     {
-    if (rewrite_rules)
+    if (tblock && tblock->rewrite_rules)
       {
       void *reset_point = store_get(0);
       header_line *hh;
 
-      if ((hh = rewrite_header(h, NULL, NULL, rewrite_rules, rewrite_existflags, FALSE)))
+      if ((hh = rewrite_header(h, NULL, NULL, tblock->rewrite_rules,
+                 tblock->rewrite_existflags, FALSE)))
        {
-       if (!sendfn(fd, hh->text, hh->slen, wck_flags)) return FALSE;
+       if (!sendfn(fd, hh->text, hh->slen, use_crlf)) return FALSE;
        store_reset(reset_point);
        continue;     /* With the next header line */
        }
@@ -691,7 +691,7 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old)
 
     /* Either no rewriting rules, or it didn't get rewritten */
 
-    if (!sendfn(fd, h->text, h->slen, wck_flags)) return FALSE;
+    if (!sendfn(fd, h->text, h->slen, use_crlf)) return FALSE;
     }
 
   /* Header removed */
@@ -726,7 +726,7 @@ if (addr)
       hprev = h;
       if (i == 1)
        {
-       if (!sendfn(fd, h->text, h->slen, wck_flags)) return FALSE;
+       if (!sendfn(fd, h->text, h->slen, use_crlf)) return FALSE;
        DEBUG(D_transport)
          debug_printf("added header line(s):\n%s---\n", h->text);
        }
@@ -740,19 +740,19 @@ up any other headers. An empty string or a forced expansion failure are
 noops. An added header string from a transport may not end with a newline;
 add one if it does not. */
 
-if (add_headers)
+if (tblock && (list = CUS tblock->add_headers))
   {
   int sep = '\n';
   uschar * s;
 
-  while ((s = string_nextinlist(CUSS &add_headers, &sep, NULL, 0)))
+  while ((s = string_nextinlist(&list, &sep, NULL, 0)))
     if ((s = expand_string(s)))
       {
       int len = Ustrlen(s);
       if (len > 0)
        {
-       if (!sendfn(fd, s, len, wck_flags)) return FALSE;
-       if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, wck_flags))
+       if (!sendfn(fd, s, len, use_crlf)) return FALSE;
+       if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, use_crlf))
          return FALSE;
        DEBUG(D_transport)
          {
@@ -768,7 +768,7 @@ if (add_headers)
 
 /* Separate headers from body with a blank line */
 
-return sendfn(fd, US"\n", 1, wck_flags);
+return sendfn(fd, US"\n", 1, use_crlf);
 }
 
 
@@ -801,31 +801,32 @@ can include timeouts for certain transports, which are requested by setting
 transport_write_timeout non-zero.
 
 Arguments:
-  addr                  (chain of) addresses (for extra headers), or NULL;
-                          only the first address is used
   fd                    file descriptor to write the message to
-  options               bit-wise options:
-    add_return_path       if TRUE, add a "return-path" header
-    add_envelope_to       if TRUE, add a "envelope-to" header
-    add_delivery_date     if TRUE, add a "delivery-date" header
-    use_crlf              if TRUE, turn NL into CR LF
-    end_dot               if TRUE, send a terminating "." line at the end
-    no_headers            if TRUE, omit the headers
-    no_body               if TRUE, omit the body
-    use_bdat             if TRUE, prepend written data with RFC3030 BDAT hdrs
-  size_limit            if > 0, this is a limit to the size of message written;
-                          it is used when returning messages to their senders,
-                          and is approximate rather than exact, owing to chunk
-                          buffering
-  add_headers           a string containing one or more headers to add; it is
-                          expanded, and must be in correct RFC 822 format as
-                          it is transmitted verbatim; NULL => no additions,
-                          and so does empty string or forced expansion fail
-  remove_headers        a colon-separated list of headers to remove, or NULL
-  check_string          a string to check for at the start of lines, or NULL
-  escape_string         a string to insert in front of any check string
-  rewrite_rules         chain of header rewriting rules
-  rewrite_existflags    flags for the rewriting rules
+  tctx
+    addr                (chain of) addresses (for extra headers), or NULL;
+                          only the first address is used
+    tblock             optional transport instance block (NULL signifies NULL/0):
+      add_headers           a string containing one or more headers to add; it is
+                            expanded, and must be in correct RFC 822 format as
+                            it is transmitted verbatim; NULL => no additions,
+                            and so does empty string or forced expansion fail
+      remove_headers        a colon-separated list of headers to remove, or NULL
+      rewrite_rules         chain of header rewriting rules
+      rewrite_existflags    flags for the rewriting rules
+    options               bit-wise options:
+      add_return_path       if TRUE, add a "return-path" header
+      add_envelope_to       if TRUE, add a "envelope-to" header
+      add_delivery_date     if TRUE, add a "delivery-date" header
+      use_crlf              if TRUE, turn NL into CR LF
+      end_dot               if TRUE, send a terminating "." line at the end
+      no_headers            if TRUE, omit the headers
+      no_body               if TRUE, omit the body
+    size_limit            if > 0, this is a limit to the size of message written;
+                            it is used when returning messages to their senders,
+                            and is approximate rather than exact, owing to chunk
+                            buffering
+    check_string          a string to check for at the start of lines, or NULL
+    escape_string         a string to insert in front of any check string
 
 Returns:                TRUE on success; FALSE (with errno) on failure.
                         In addition, the global variable transport_count
@@ -833,12 +834,10 @@ Returns:                TRUE on success; FALSE (with errno) on failure.
 */
 
 static BOOL
-internal_transport_write_message(address_item *addr, int fd, int options,
-  int size_limit, uschar *add_headers, uschar *remove_headers, uschar *check_string,
-  uschar *escape_string, rewrite_rule *rewrite_rules, int rewrite_existflags)
+internal_transport_write_message(int fd, transport_ctx * tctx, int size_limit)
 {
 int len;
-unsigned wck_flags = (unsigned) options;
+unsigned wck_flags = (unsigned) tctx->options;
 off_t fsize;
 int size;
 
@@ -849,11 +848,11 @@ chunk_ptr = deliver_out_buffer;
 /* Set up the data for start-of-line data checking and escaping */
 
 nl_partial_match = -1;
-if (check_string && escape_string)
+if (tctx->check_string && tctx->escape_string)
   {
-  nl_check = check_string;
+  nl_check = tctx->check_string;
   nl_check_length = Ustrlen(nl_check);
-  nl_escape = escape_string;
+  nl_escape = tctx->escape_string;
   nl_escape_length = Ustrlen(nl_escape);
   }
 else
@@ -863,17 +862,17 @@ else
 an option (set for SMTP, not otherwise). Negate the length if not wanted till
 after the headers. */
 
-if (!(options & topt_escape_headers))
+if (!(tctx->options & topt_escape_headers))
   nl_check_length = -nl_check_length;
 
 /* Write the headers if required, including any that have to be added. If there
 are header rewriting rules, apply them. */
 
-if (!(options & topt_no_headers))
+if (!(tctx->options & topt_no_headers))
   {
   /* Add return-path: if requested. */
 
-  if (options & topt_add_return_path)
+  if (tctx->options & topt_add_return_path)
     {
     uschar buffer[ADDRESS_MAXLENGTH + 20];
     int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH,
@@ -883,7 +882,7 @@ if (!(options & topt_no_headers))
 
   /* Add envelope-to: if requested */
 
-  if (options & topt_add_envelope_to)
+  if (tctx->options & topt_add_envelope_to)
     {
     BOOL first = TRUE;
     address_item *p;
@@ -897,7 +896,7 @@ if (!(options & topt_no_headers))
     anchors for lists of addresses already handled; they have to be defined at
     this level becuase write_env_to() calls itself recursively. */
 
-    for (p = addr; p; p = p->next)
+    for (p = tctx->addr; p; p = p->next)
       if (!write_env_to(p, &plist, &dlist, &first, fd, wck_flags))
        return FALSE;
 
@@ -909,7 +908,7 @@ if (!(options & topt_no_headers))
 
   /* Add delivery-date: if requested. */
 
-  if (options & topt_add_delivery_date)
+  if (tctx->options & topt_add_delivery_date)
     {
     uschar buffer[100];
     int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
@@ -921,8 +920,8 @@ if (!(options & topt_no_headers))
   were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
   match any entries therein. Then check addr->prop.remove_headers too, provided that
   addr is not NULL. */
-  if (!transport_headers_send(addr, fd, add_headers, remove_headers, &write_chunk,
-       wck_flags, rewrite_rules, rewrite_existflags))
+
+  if (!transport_headers_send(tctx->addr, fd, tctx->tblock, &write_chunk, wck_flags))
     return FALSE;
   }
 
@@ -933,18 +932,18 @@ flush that buffer with non-last BDAT prependix) plus the amount of body data
 (as expanded for CRLF lines).  Then create and write the BDAT, and ensure
 that further use of write_chunk() will not prepend BDATs.  */
 
-if (options & topt_use_bdat)
+if (tctx->options & topt_use_bdat)
   {
   if ((size = chunk_ptr - deliver_out_buffer) < 0)
     size = 0;
-  if (!(options & topt_no_body))
+  if (!(tctx->options & topt_no_body))
     {
     if ((fsize = lseek(deliver_datafile, 0, SEEK_END)) < 0) return FALSE;
     fsize -= SPOOL_DATA_START_OFFSET;
     if (size_limit > 0  &&  fsize > size_limit)
       fsize = size_limit;
     size += fsize;
-    if (options & topt_use_crlf)
+    if (tctx->options & topt_use_crlf)
       size += body_linecount;  /* account for CRLF-expansion */
     }
 
@@ -972,7 +971,7 @@ negative in cases where it isn't to apply to the headers). Then ensure the body
 is positioned at the start of its file (following the message id), then write
 it, applying the size limit if required. */
 
-if (!(options & topt_no_body))
+if (!(tctx->options & topt_no_body))
   {
   nl_check_length = abs(nl_check_length);
   nl_partial_match = 0;
@@ -994,7 +993,7 @@ nl_check_length = nl_escape_length = 0;
 
 /* If requested, add a terminating "." line (SMTP output). */
 
-if (options & topt_end_dot && !write_chunk(fd, US".\n", 2, wck_flags))
+if (tctx->options & topt_end_dot && !write_chunk(fd, US".\n", 2, wck_flags))
   return FALSE;
 
 /* Write out any remaining data in the buffer before returning. */
@@ -1026,10 +1025,8 @@ Returns:       TRUE on success; FALSE (with errno) for any failure
 */
 
 BOOL
-dkim_transport_write_message(address_item *addr, int out_fd, int options,
-  uschar *add_headers, uschar *remove_headers,
-  uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules,
-  int rewrite_existflags, struct ob_dkim * dkim)
+dkim_transport_write_message(int out_fd, transport_ctx * tctx,
+  struct ob_dkim * dkim)
 {
 int dkim_fd;
 int save_errno = 0;
@@ -1044,10 +1041,7 @@ off_t k_file_size;
 /* If we can't sign, just call the original function. */
 
 if (!(dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector))
-  return transport_write_message(addr, out_fd, options,
-           0, add_headers, remove_headers,
-           check_string, escape_string, rewrite_rules,
-           rewrite_existflags);
+  return transport_write_message(out_fd, tctx, 0);
 
 dkim_spool_name = spool_fname(US"input", message_subdir, message_id,
                    string_sprintf("-%d-K", (int)getpid()));
@@ -1062,10 +1056,8 @@ if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0)
 
 /* Call original function to write the -K file; does the CRLF expansion */
 
-rc = transport_write_message(addr, dkim_fd, options,
-  0, add_headers, remove_headers,
-  check_string, escape_string, rewrite_rules,
-  rewrite_existflags);
+tctx->options &= ~topt_use_bdat;
+rc = transport_write_message(dkim_fd, tctx, 0);
 
 /* Save error state. We must clean up before returning. */
 if (!rc)
@@ -1217,6 +1209,7 @@ set up a filtering process, fork another process to call the internal function
 to write to the filter, and in this process just suck from the filter and write
 down the given fd. At the end, tidy up the pipes and the processes.
 
+XXX
 Arguments:     as for internal_transport_write_message() above
 
 Returns:       TRUE on success; FALSE (with errno) for any failure
@@ -1224,16 +1217,16 @@ Returns:       TRUE on success; FALSE (with errno) for any failure
 */
 
 BOOL
-transport_write_message(address_item *addr, int fd, int options,
-  int size_limit, uschar *add_headers, uschar *remove_headers,
-  uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules,
-  int rewrite_existflags)
+transport_write_message(int fd, transport_ctx * tctx, int size_limit)
 {
 unsigned wck_flags;
 BOOL last_filter_was_NL = TRUE;
 int rc, len, yield, fd_read, fd_write, save_errno;
 int pfd[2] = {-1, -1};
 pid_t filter_pid, write_pid;
+static transport_ctx dummy_tctx = { NULL, NULL, NULL, NULL, 0 };
+
+if (!tctx) tctx = &dummy_tctx;
 
 transport_filter_timed_out = FALSE;
 
@@ -1244,22 +1237,20 @@ if (  !transport_filter_argv
    || !*transport_filter_argv
    || !**transport_filter_argv
    )
-  return internal_transport_write_message(addr, fd, options, size_limit,
-    add_headers, remove_headers, check_string, escape_string,
-    rewrite_rules, rewrite_existflags);
+  return internal_transport_write_message(fd, tctx, size_limit);
 
 /* Otherwise the message must be written to a filter process and read back
 before being written to the incoming fd. First set up the special processing to
 be done during the copying. */
 
-wck_flags = options & topt_use_crlf;
+wck_flags = tctx->options & topt_use_crlf;
 nl_partial_match = -1;
 
-if (check_string != NULL && escape_string != NULL)
+if (tctx->check_string && tctx->escape_string)
   {
-  nl_check = check_string;
+  nl_check = tctx->check_string;
   nl_check_length = Ustrlen(nl_check);
-  nl_escape = escape_string;
+  nl_escape = tctx->escape_string;
   nl_escape_length = Ustrlen(nl_escape);
   }
 else nl_check_length = nl_escape_length = 0;
@@ -1283,7 +1274,7 @@ filter_pid = child_open(USS transport_filter_argv, NULL, 077,
 if (filter_pid < 0) goto TIDY_UP;      /* errno set */
 
 DEBUG(D_transport)
-  debug_printf("process %d running as transport filter: write=%d read=%d\n",
+  debug_printf("process %d running as transport filter: fd_write=%d fd_read=%d\n",
     (int)filter_pid, fd_write, fd_read);
 
 /* Fork subprocess to write the message to the filter, and return the result
@@ -1297,16 +1288,18 @@ if ((write_pid = fork()) == 0)
   (void)close(fd_read);
   (void)close(pfd[pipe_read]);
   nl_check_length = nl_escape_length = 0;
-  rc = internal_transport_write_message(addr, fd_write,
-    (options & ~(topt_use_crlf | topt_end_dot)),
-    size_limit, add_headers, remove_headers, NULL, NULL,
-    rewrite_rules, rewrite_existflags);
+
+  tctx->check_string = tctx->escape_string = NULL;
+  tctx->options &= ~(topt_use_crlf | topt_end_dot | topt_use_bdat);
+
+  rc = internal_transport_write_message(fd_write, tctx, size_limit);
+
   save_errno = errno;
   if (  write(pfd[pipe_write], (void *)&rc, sizeof(BOOL))
         != sizeof(BOOL)
      || write(pfd[pipe_write], (void *)&save_errno, sizeof(int))
         != sizeof(int)
-     || write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int))
+     || write(pfd[pipe_write], (void *)&tctx->addr->more_errno, sizeof(int))
         != sizeof(int)
      )
     rc = FALSE;        /* compiler quietening */
@@ -1403,7 +1396,7 @@ if (filter_pid > 0 && (rc = child_close(filter_pid, 30)) != 0 && yield)
   {
   yield = FALSE;
   save_errno = ERRNO_FILTER_FAIL;
-  addr->more_errno = rc;
+  tctx->addr->more_errno = rc;
   DEBUG(D_transport) debug_printf("filter process returned %d\n", rc);
   }
 
@@ -1424,7 +1417,7 @@ if (write_pid > 0)
       if (!ok)
         {
         dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
-        dummy = read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int));
+        dummy = read(pfd[pipe_read], (void *)&(tctx->addr->more_errno), sizeof(int));
         yield = FALSE;
         }
       }
@@ -1432,7 +1425,7 @@ if (write_pid > 0)
       {
       yield = FALSE;
       save_errno = ERRNO_FILTER_FAIL;
-      addr->more_errno = rc;
+      tctx->addr->more_errno = rc;
       DEBUG(D_transport) debug_printf("writing process returned %d\n", rc);
       }
     }
@@ -1446,7 +1439,7 @@ filter was not NL, insert a NL to make the SMTP protocol work. */
 if (yield)
   {
   nl_check_length = nl_escape_length = 0;
-  if (  options & topt_end_dot
+  if (  tctx->options & topt_end_dot
      && ( last_filter_was_NL
         ? !write_chunk(fd, US".\n", 2, wck_flags)
        : !write_chunk(fd, US"\n.\n", 3, wck_flags)
@@ -1466,7 +1459,7 @@ DEBUG(D_transport)
   {
   debug_printf("end of filtering transport writing: yield=%d\n", yield);
   if (!yield)
-    debug_printf("errno=%d more_errno=%d\n", errno, addr->more_errno);
+    debug_printf("errno=%d more_errno=%d\n", errno, tctx->addr->more_errno);
   }
 
 return yield;
index 5dc4ee9b5df4150fb5de5372af49fc644fb4d654..c9d15052588fbf8b99047f8e3835297f161f4e9c 100644 (file)
@@ -2874,9 +2874,14 @@ at initialization time. */
 
 if (yield == OK)
   {
-  if (!transport_write_message(addr, fd, ob->options, 0, tblock->add_headers,
-      tblock->remove_headers, ob->check_string, ob->escape_string,
-      tblock->rewrite_rules, tblock->rewrite_existflags))
+  transport_ctx tctx = {
+    tblock,
+    addr,
+    ob->check_string,
+    ob->escape_string,
+    ob->options
+  };
+  if (!transport_write_message(fd, &tctx, 0))
     yield = DEFER;
   }
 
index 54f9ef4de3fb276b5d1c2b79d6b436e163f7ea21..36a68b92cb78492d39bb0d80f3bcc179d37b60fa 100644 (file)
@@ -691,6 +691,17 @@ if (return_message)
     US"------ This is a copy of the body of the message, without the headers.\n"
     :
     US"------ This is a copy of the message, including all the headers.\n";
+  transport_ctx tctx = {
+    tblock,
+    addr,
+    NULL,
+    NULL,
+    (tblock->body_only ? topt_no_headers : 0) |
+    (tblock->headers_only ? topt_no_body : 0) |
+    (tblock->return_path_add ? topt_add_return_path : 0) |
+    (tblock->delivery_date_add ? topt_add_delivery_date : 0) |
+    (tblock->envelope_to_add ? topt_add_envelope_to : 0)
+  };
 
   if (bounce_return_size_limit > 0 && !tblock->headers_only)
     {
@@ -710,14 +721,7 @@ if (return_message)
 
   fflush(f);
   transport_count = 0;
-  transport_write_message(addr, fileno(f),
-    (tblock->body_only? topt_no_headers : 0) |
-    (tblock->headers_only? topt_no_body : 0) |
-    (tblock->return_path_add? topt_add_return_path : 0) |
-    (tblock->delivery_date_add? topt_add_delivery_date : 0) |
-    (tblock->envelope_to_add? topt_add_envelope_to : 0),
-    bounce_return_size_limit, tblock->add_headers, tblock->remove_headers,
-    NULL, NULL, tblock->rewrite_rules, tblock->rewrite_existflags);
+  transport_write_message(fileno(f), &tctx, bounce_return_size_limit);
   }
 
 /* End the message and wait for the child process to end; no timeout. */
index bca597893dc7ca76bb0e2dd3cdd45c0e55213416..9624ece6af2a656667b999d8aae937497feec140 100644 (file)
@@ -609,6 +609,13 @@ for (addr = addrlist; addr != NULL; addr = addr->next)
 if (send_data)
   {
   BOOL ok;
+  transport_ctx tctx = {
+    tblock,
+    addrlist,
+    US".",
+    US"..",
+    ob->options
+  };
 
   if (!lmtp_write_command(fd_in, "DATA\r\n")) goto WRITE_FAILED;
   if (!lmtp_read_response(out, buffer, sizeof(buffer), '3', timeout))
@@ -628,9 +635,7 @@ if (send_data)
     debug_printf("  LMTP>> writing message and terminating \".\"\n");
 
   transport_count = 0;
-  ok = transport_write_message(addrlist, fd_in, ob->options, 0,
-        tblock->add_headers, tblock->remove_headers, US".", US"..",
-        tblock->rewrite_rules, tblock->rewrite_existflags);
+  ok = transport_write_message(fd_in, &tctx, 0);
 
   /* Failure can either be some kind of I/O disaster (including timeout),
   or the failure of a transport filter or the expansion of added headers. */
index db522e54bdc65be91f76673919f0610d7321df7b..e3d01974a8d7c30fa9ff44c045874dc26324abd2 100644 (file)
@@ -555,6 +555,13 @@ uschar *envp[50];
 const uschar *envlist = ob->environment;
 uschar *cmd, *ss;
 uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n";
+transport_ctx tctx = {
+  tblock,
+  addr,
+  ob->check_string,
+  ob->escape_string,
+  ob->options /* set at initialization time */
+};
 
 DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
 
@@ -842,23 +849,19 @@ if (ob->use_bsmtp)
   if (!transport_write_string(fd_in, "MAIL FROM:<%s>%s", return_path, eol))
     goto END_WRITE;
 
-  for (a = addr; a != NULL; a = a->next)
-    {
+  for (a = addr; a; a = a->next)
     if (!transport_write_string(fd_in,
         "RCPT TO:<%s>%s",
         transport_rcpt_address(a, tblock->rcpt_include_affixes),
         eol))
       goto END_WRITE;
-    }
 
   if (!transport_write_string(fd_in, "DATA%s", eol)) goto END_WRITE;
   }
 
-/* Now the actual message - the options were set at initialization time */
+/* Now the actual message */
 
-if (!transport_write_message(addr, fd_in, ob->options, 0, tblock->add_headers,
-  tblock->remove_headers, ob->check_string, ob->escape_string,
-  tblock->rewrite_rules, tblock->rewrite_existflags))
+if (!transport_write_message(fd_in, &tctx, 0))
     goto END_WRITE;
 
 /* Now any configured suffix */
index fa5711b990795fd509fa64ce3945c0d4cb22b30c..33de45cd71c8947995e50c53c1b4d78f5152541f 100644 (file)
@@ -2358,24 +2358,25 @@ if (!ok)
   ok = TRUE;
 else
   {
-  int options = topt_use_crlf | topt_escape_headers
-    | (tblock->body_only       ? topt_no_headers       : 0)
-    | (tblock->headers_only    ? topt_no_body          : 0)
-    | (tblock->return_path_add ? topt_add_return_path  : 0)
-    | (tblock->delivery_date_add ?topt_add_delivery_date :0)
-    | (tblock->envelope_to_add ? topt_add_envelope_to  : 0);
-  uschar * str_spot, * str_repl;
+  transport_ctx tctx = {
+    tblock,
+    addrlist,
+    US".", US"..",    /* Escaping strings */
+    topt_use_crlf | topt_escape_headers
+    | (tblock->body_only       ? topt_no_headers : 0)
+    | (tblock->headers_only    ? topt_no_body : 0)
+    | (tblock->return_path_add ? topt_add_return_path : 0)
+    | (tblock->delivery_date_add ? topt_add_delivery_date : 0)
+    | (tblock->envelope_to_add ? topt_add_envelope_to : 0)
+  };
 
   if (peer_offered & PEER_OFFERED_CHUNKING)
     {
-    options |= topt_use_bdat;
-    str_spot = str_repl = NULL;
+    tctx.options |= topt_use_bdat;
+    tctx.check_string = tctx.escape_string = NULL;
     }
   else
-    {
-    options |= topt_end_dot;
-    str_spot = US"."; str_repl = US"..";
-    }
+    tctx.options |= topt_end_dot;
 
   sigalrm_seen = FALSE;
   transport_write_timeout = ob->data_timeout;
@@ -2387,20 +2388,9 @@ else
   transport_count = 0;
 
 #ifndef DISABLE_DKIM
-  ok = dkim_transport_write_message(addrlist, inblock.sock,
-    options,
-    tblock->add_headers, tblock->remove_headers,
-    str_spot, str_repl,        /* Escaping strings */
-    tblock->rewrite_rules, tblock->rewrite_existflags,
-    &ob->dkim
-    );
+  ok = dkim_transport_write_message(inblock.sock, &tctx, &ob->dkim);
 #else
-  ok = transport_write_message(addrlist, inblock.sock,
-    options,
-    0,            /* No size limit */
-    tblock->add_headers, tblock->remove_headers,
-    str_spot, str_repl,        /* Escaping strings */
-    tblock->rewrite_rules, tblock->rewrite_existflags);
+  ok = transport_write_message(inblock.sock, &tctx, 0);
 #endif
 
   /* transport_write_message() uses write() because it is called from other
index 7e0f066f9147abc230b354ec77bc85f91fd3226e..f5f478edd8575ec94eba819301023a040d8285dd 100644 (file)
@@ -1589,11 +1589,8 @@ if(cutthrough.fd < 0)
 HDEBUG(D_acl) debug_printf("----------- start cutthrough headers send -----------\n");
 
 if (!transport_headers_send(&cutthrough.addr, cutthrough.fd,
-       cutthrough.addr.transport->add_headers,
-       cutthrough.addr.transport->remove_headers,
-       &cutthrough_write_chunk, topt_use_crlf,
-       cutthrough.addr.transport->rewrite_rules,
-       cutthrough.addr.transport->rewrite_existflags))
+       cutthrough.addr.transport,
+       &cutthrough_write_chunk, topt_use_crlf))
   return FALSE;
 
 HDEBUG(D_acl) debug_printf("----------- done cutthrough headers send ------------\n");
index c40aa6f52d7ae4b7018d1f57f58703b6ac2ce562..673d9e6f948e37a33cf247278311a00dbd1d4e3e 100644 (file)
@@ -27,7 +27,7 @@ lock file created
 mailbox TESTSUITE/test-mail/userx is locked
 writing to file TESTSUITE/test-mail/userx
 writing data block fd=dddd size=sss timeout=0
-process pppp running as transport filter: write=dddd read=dddd
+process pppp running as transport filter: fd_write=10 fd_read=11
 writing data block fd=dddd size=sss timeout=0
 process pppp writing to transport filter
 copying from the filter