{
uschar *start = chunk;
uschar *end = chunk + len;
-register uschar *ptr;
+uschar *ptr;
int mlen = DELIVER_OUT_BUFFER_SIZE - nl_escape_length - 2;
/* The assumption is made that the check string will never stretch over move
for (ptr = start; ptr < end; ptr++)
{
- register int ch;
+ int ch;
/* Flush the buffer if it has reached the threshold - we want to leave enough
room for the next uschar, plus a possible extra CR for an LF, plus the escape
/* Do nothing if we have already handled this address. If not, remember it
so that we don't handle it again. */
-for (ppp = *pdlist; ppp != NULL; ppp = ppp->next)
- { if (p == ppp->ptr) return TRUE; }
+for (ppp = *pdlist; ppp; ppp = ppp->next) if (p == ppp->ptr) return TRUE;
ppp = store_get(sizeof(struct aci));
ppp->next = *pdlist;
for (pp = p;; pp = pp->parent)
{
address_item *dup;
- for (dup = addr_duplicate; dup != NULL; dup = dup->next)
- {
- if (dup->dupof != pp) continue; /* Not a dup of our address */
- if (!write_env_to(dup, pplist, pdlist, first, fd, use_crlf)) return FALSE;
- }
- if (pp->parent == NULL) break;
+ for (dup = addr_duplicate; dup; dup = dup->next)
+ if (dup->dupof == pp) /* a dup of our address */
+ if (!write_env_to(dup, pplist, pdlist, first, fd, use_crlf))
+ return FALSE;
+ if (!pp->parent) break;
}
/* Check to see if we have already output the progenitor. */
-for (ppp = *pplist; ppp != NULL; ppp = ppp->next)
- { if (pp == ppp->ptr) break; }
-if (ppp != NULL) return TRUE;
+for (ppp = *pplist; ppp; ppp = ppp->next) if (pp == ppp->ptr) break;
+if (ppp) return TRUE;
/* Remember what we have output, and output it. */
separately and squash any empty ones.
Then check addr->prop.remove_headers too, provided that addr is not NULL. */
-for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
+for (h = header_list; h; h = h->next) if (h->type != htype_old)
{
int i;
const uschar *list = remove_headers;
header_line *hprev = addr->prop.extra_headers;
header_line *hnext;
for (i = 0; i < 2; i++)
- {
- for (h = hprev, hprev = NULL; h != NULL; h = hnext)
+ for (h = hprev, hprev = NULL; h; h = hnext)
{
hnext = h->next;
h->next = hprev;
debug_printf("added header line(s):\n%s---\n", h->text);
}
}
- }
}
/* If a string containing additional headers exists it is a newline-sep
uschar * s;
while ((s = string_nextinlist(CUSS &add_headers, &sep, NULL, 0)))
- if (!(s = expand_string(s)))
- {
- if (!expand_string_forcedfail)
- { errno = ERRNO_CHHEADER_FAIL; return FALSE; }
- }
- else
+ if ((s = expand_string(s)))
{
int len = Ustrlen(s);
if (len > 0)
}
}
}
+ else if (!expand_string_forcedfail)
+ { errno = ERRNO_CHHEADER_FAIL; return FALSE; }
}
/* Separate headers from body with a blank line */
/* Set up the data for start-of-line data checking and escaping */
nl_partial_match = -1;
-if (check_string != NULL && escape_string != NULL)
+if (check_string && escape_string)
{
nl_check = check_string;
nl_check_length = Ustrlen(nl_check);
nl_escape = escape_string;
nl_escape_length = Ustrlen(nl_escape);
}
-else nl_check_length = nl_escape_length = 0;
+else
+ nl_check_length = nl_escape_length = 0;
/* Whether the escaping mechanism is applied to headers or not is controlled by
an option (set for SMTP, not otherwise). Negate the length if not wanted till
after the headers. */
-if ((options & topt_escape_headers) == 0) nl_check_length = -nl_check_length;
+if (!(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) == 0)
+if (!(options & topt_no_headers))
{
/* Add return-path: if requested. */
- if ((options & topt_add_return_path) != 0)
+ if (options & topt_add_return_path)
{
uschar buffer[ADDRESS_MAXLENGTH + 20];
- sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH,
+ int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH,
return_path);
- if (!write_chunk(fd, buffer, Ustrlen(buffer), use_crlf)) return FALSE;
+ if (!write_chunk(fd, buffer, n, use_crlf)) return FALSE;
}
/* Add envelope-to: if requested */
- if ((options & topt_add_envelope_to) != 0)
+ if (options & topt_add_envelope_to)
{
BOOL first = TRUE;
address_item *p;
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 != NULL; p = p->next)
- {
- if (!write_env_to(p, &plist, &dlist, &first, fd, use_crlf)) return FALSE;
- }
+ for (p = addr; p; p = p->next)
+ if (!write_env_to(p, &plist, &dlist, &first, fd, use_crlf))
+ return FALSE;
/* Add a final newline and reset the store used for tracking duplicates */
if ((options & topt_add_delivery_date) != 0)
{
uschar buffer[100];
- sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
- if (!write_chunk(fd, buffer, Ustrlen(buffer), use_crlf)) return FALSE;
+ int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
+ if (!write_chunk(fd, buffer, n, use_crlf)) return FALSE;
}
/* Then the message's headers. Don't write any that are flagged as "old";
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) == 0)
+if (!(options & topt_no_body))
{
nl_check_length = abs(nl_check_length);
nl_partial_match = 0;
/* If requested, add a terminating "." line (SMTP output). */
-if ((options & topt_end_dot) != 0 && !write_chunk(fd, US".\n", 2, use_crlf))
+if (options & topt_end_dot && !write_chunk(fd, US".\n", 2, use_crlf))
return FALSE;
/* Write out any remaining data in the buffer before returning. */
signing the file, send the signed message down the original fd (or TLS fd).
Arguments:
- as for internal_transport_write_message() above, with additional arguments:
- uschar *dkim_private_key DKIM: The private key to use (filename or
- plain data)
- uschar *dkim_domain DKIM: The domain to use
- uschar *dkim_selector DKIM: The selector to use.
- uschar *dkim_canon DKIM: The canonalization scheme to use,
- "simple" or "relaxed"
- uschar *dkim_strict DKIM: What to do if signing fails:
- 1/true => throw error
- 0/false => send anyway
- uschar *dkim_sign_headers DKIM: List of headers that should be included
- in signature generation
+ as for internal_transport_write_message() above, with additional arguments
+ for DKIM.
Returns: TRUE on success; FALSE (with errno) for any failure
*/
BOOL
-dkim_transport_write_message(address_item *addr, int fd, int options,
- int size_limit, uschar *add_headers, uschar *remove_headers,
+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, uschar *dkim_private_key, uschar *dkim_domain,
- uschar *dkim_selector, uschar *dkim_canon, uschar *dkim_strict, uschar *dkim_sign_headers
- )
+ int rewrite_existflags, struct ob_dkim * dkim)
{
int dkim_fd;
int save_errno = 0;
BOOL rc;
uschar * dkim_spool_name;
-char sbuf[2048];
int sread = 0;
int wwritten = 0;
uschar *dkim_signature = NULL;
+off_t k_file_size;
/* If we can't sign, just call the original function. */
-if (!(dkim_private_key && dkim_domain && dkim_selector))
- return transport_write_message(addr, fd, options,
- size_limit, add_headers, remove_headers,
+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);
goto CLEANUP;
}
-/* Call original function to write the -K file */
+/* Call original function to write the -K file; does the CRLF expansion */
rc = transport_write_message(addr, dkim_fd, options,
- size_limit, add_headers, remove_headers,
+ 0, add_headers, remove_headers,
check_string, escape_string, rewrite_rules,
rewrite_existflags);
goto CLEANUP;
}
-if (dkim_private_key && dkim_domain && dkim_selector)
+if (dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector)
{
/* Rewind file and feed it to the goats^W DKIM lib */
lseek(dkim_fd, 0, SEEK_SET);
dkim_signature = dkim_exim_sign(dkim_fd,
- dkim_private_key,
- dkim_domain,
- dkim_selector,
- dkim_canon,
- dkim_sign_headers);
+ dkim->dkim_private_key,
+ dkim->dkim_domain,
+ dkim->dkim_selector,
+ dkim->dkim_canon,
+ dkim->dkim_sign_headers);
if (!dkim_signature)
{
- if (dkim_strict)
+ if (dkim->dkim_strict)
{
- uschar *dkim_strict_result = expand_string(dkim_strict);
+ uschar *dkim_strict_result = expand_string(dkim->dkim_strict);
if (dkim_strict_result)
- if ( (strcmpic(dkim_strict,US"1") == 0) ||
- (strcmpic(dkim_strict,US"true") == 0) )
+ if ( (strcmpic(dkim->dkim_strict,US"1") == 0) ||
+ (strcmpic(dkim->dkim_strict,US"true") == 0) )
{
/* Set errno to something halfway meaningful */
save_errno = EACCES;
}
}
}
- else
+
+ if (dkim_signature)
{
int siglen = Ustrlen(dkim_signature);
while(siglen > 0)
{
-#ifdef SUPPORT_TLS
- wwritten = tls_out.active == fd
- ? tls_write(FALSE, dkim_signature, siglen)
- : write(fd, dkim_signature, siglen);
-#else
- wwritten = write(fd, dkim_signature, siglen);
-#endif
+ #ifdef SUPPORT_TLS
+ wwritten = tls_out.active == out_fd
+ ? tls_write(FALSE, dkim_signature, siglen)
+ : write(out_fd, dkim_signature, siglen);
+ #else
+ wwritten = write(out_fd, dkim_signature, siglen);
+ #endif
if (wwritten == -1)
- {
+ {
/* error, bail out */
save_errno = errno;
rc = FALSE;
to the socket. However only if we don't use TLS,
as then there's another layer of indirection
before the data finally hits the socket. */
-if (tls_out.active != fd)
+if (tls_out.active != out_fd)
{
- off_t size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */
ssize_t copied = 0;
off_t offset = 0;
+ k_file_size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */
+
/* Rewind file */
lseek(dkim_fd, 0, SEEK_SET);
- while(copied >= 0 && offset < size)
- copied = sendfile(fd, dkim_fd, &offset, size - offset);
+ while(copied >= 0 && offset < k_file_size)
+ copied = sendfile(out_fd, dkim_fd, &offset, k_file_size - offset);
if (copied < 0)
{
save_errno = errno;
lseek(dkim_fd, 0, SEEK_SET);
/* Send file down the original fd */
- while((sread = read(dkim_fd, sbuf, 2048)) > 0)
+ while((sread = read(dkim_fd, deliver_out_buffer, DELIVER_OUT_BUFFER_SIZE)) >0)
{
- char *p = sbuf;
+ char *p = deliver_out_buffer;
/* write the chunk */
while (sread)
{
#ifdef SUPPORT_TLS
- wwritten = tls_out.active == fd
+ wwritten = tls_out.active == out_fd
? tls_write(FALSE, US p, sread)
- : write(fd, p, sread);
+ : write(out_fd, p, sread);
#else
- wwritten = write(fd, p, sread);
+ wwritten = write(out_fd, p, sread);
#endif
if (wwritten == -1)
{
if (yield)
{
nl_check_length = nl_escape_length = 0;
- if ((options & topt_end_dot) != 0 && (last_filter_was_NL?
- !write_chunk(fd, US".\n", 2, use_crlf) :
- !write_chunk(fd, US"\n.\n", 3, use_crlf)))
- {
+ if ( options & topt_end_dot
+ && ( last_filter_was_NL
+ ? !write_chunk(fd, US".\n", 2, options)
+ : !write_chunk(fd, US"\n.\n", 3, options)
+ ) )
yield = FALSE;
- }
/* Write out any remaining data in the buffer. */
else
- {
- yield = (len = chunk_ptr - deliver_out_buffer) <= 0 ||
- transport_write_block(fd, deliver_out_buffer, len);
- }
+ yield = (len = chunk_ptr - deliver_out_buffer) <= 0
+ || transport_write_block(fd, deliver_out_buffer, len);
}
-else errno = save_errno; /* From some earlier error */
+else
+ errno = save_errno; /* From some earlier error */
DEBUG(D_transport)
{
(void *)offsetof(smtp_transport_options_block, delay_after_cutoff) },
#ifndef DISABLE_DKIM
{ "dkim_canon", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_canon) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_canon) },
{ "dkim_domain", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_domain) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_domain) },
{ "dkim_private_key", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_private_key) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_private_key) },
{ "dkim_selector", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_selector) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_selector) },
{ "dkim_sign_headers", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_sign_headers) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_sign_headers) },
{ "dkim_strict", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_strict) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_strict) },
#endif
{ "dns_qualify_single", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
US"*" /* tls_verify_cert_hostnames */
#endif
#ifndef DISABLE_DKIM
- ,NULL, /* dkim_canon */
- NULL, /* dkim_domain */
- NULL, /* dkim_private_key */
- NULL, /* dkim_selector */
- NULL, /* dkim_sign_headers */
- NULL /* dkim_strict */
+ , {NULL, /* dkim_canon */
+ NULL, /* dkim_domain */
+ NULL, /* dkim_private_key */
+ NULL, /* dkim_selector */
+ NULL, /* dkim_sign_headers */
+ NULL} /* dkim_strict */
#endif
};
ehlo_response(uschar * buf, size_t bsize, uschar checks)
{
#ifdef SUPPORT_TLS
-if (checks & PEER_OFFERED_TLS)
- if (pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_TLS;
+if ( checks & PEER_OFFERED_TLS
+ && pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_TLS;
#endif
- if ( checks & PEER_OFFERED_IGNQ
- && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
- PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_IGNQ;
+if ( checks & PEER_OFFERED_IGNQ
+ && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
+ PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_IGNQ;
#ifndef DISABLE_PRDR
- if ( checks & PEER_OFFERED_PRDR
- && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_PRDR;
+if ( checks & PEER_OFFERED_PRDR
+ && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_PRDR;
#endif
#ifdef SUPPORT_I18N
- if ( checks & PEER_OFFERED_UTF8
- && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_UTF8;
+if ( checks & PEER_OFFERED_UTF8
+ && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_UTF8;
#endif
- if ( checks & PEER_OFFERED_DSN
- && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_DSN;
+if ( checks & PEER_OFFERED_DSN
+ && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_DSN;
- if ( checks & PEER_OFFERED_PIPE
- && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
- PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_PIPE;
+if ( checks & PEER_OFFERED_PIPE
+ && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
+ PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_PIPE;
- if ( checks & PEER_OFFERED_SIZE
- && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_SIZE;
+if ( checks & PEER_OFFERED_SIZE
+ && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_SIZE;
return checks;
}
if (esmtp || lmtp)
peer_offered = ehlo_response(buffer, Ustrlen(buffer),
- PEER_OFFERED_TLS
- | 0 /* IGNQ checked later */
- | 0 /* PRDR checked later */
- | 0 /* UTF8 checked later */
- | 0 /* DSN checked later */
- | 0 /* PIPE checked later */
- | 0 /* SIZE checked later */
+ PEER_OFFERED_TLS /* others checked later */
);
/* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
{
if (dsn_ret == dsn_ret_hdrs)
{
- Ustrcpy(p, " RET=HDRS");
- while (*p) p++;
+ Ustrcpy(p, " RET=HDRS"); p += 9;
}
else if (dsn_ret == dsn_ret_full)
{
- Ustrcpy(p, " RET=FULL");
- while (*p) p++;
+ Ustrcpy(p, " RET=FULL"); p += 9;
}
if (dsn_envid != NULL)
{
that max_rcpt will be large, so all addresses will be done at once. */
for (addr = first_addr;
- address_count < max_rcpt && addr != NULL;
+ addr && address_count < max_rcpt;
addr = addr->next)
{
int count;
if (addr->transport_return != PENDING_DEFER) continue;
address_count++;
- no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next != NULL);
+ no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next);
/* Add any DSN flags to the rcpt command and add to the sent string */
p = buffer;
*p = 0;
- if (smtp_use_dsn && (addr->dsn_flags & rf_dsnlasthop) != 1)
+ if (smtp_use_dsn && !(addr->dsn_flags & rf_dsnlasthop))
{
if ((addr->dsn_flags & rf_dsnflags) != 0)
{
}
}
- if (addr->dsn_orcpt != NULL)
+ if (addr->dsn_orcpt)
{
string_format(p, sizeof(buffer) - (p-buffer), " ORCPT=%s",
addr->dsn_orcpt);
well as body. Set the appropriate timeout value to be used for each chunk.
(Haven't been able to make it work using select() for writing yet.) */
-if (!ok) ok = TRUE; else
+if (!ok)
+ ok = TRUE;
+else
{
sigalrm_seen = FALSE;
transport_write_timeout = ob->data_timeout;
(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),
- 0, /* No size limit */
tblock->add_headers, tblock->remove_headers,
US".", US"..", /* Escaping strings */
tblock->rewrite_rules, tblock->rewrite_existflags,
- ob->dkim_private_key, ob->dkim_domain, ob->dkim_selector,
- ob->dkim_canon, ob->dkim_strict, ob->dkim_sign_headers
+ &ob->dkim
);
#else
ok = transport_write_message(addrlist, inblock.sock,