Patch from Mark Zealey.
Fixes bug 1055.
routers, and transports run) the count is increased to include the
&'Received:'& header line that Exim standardly adds, and also any other header
lines that are added by ACLs. The blank line that separates the message header
routers, and transports run) the count is increased to include the
&'Received:'& header line that Exim standardly adds, and also any other header
lines that are added by ACLs. The blank line that separates the message header
-from the body is not counted. Here is an example of the use of this variable in
-a DATA ACL:
+from the body is not counted.
+
+As with the special case of &$message_size$&, during the expansion of the
+appendfile transport's maildir_tag option in maildir format, the value of
+&$message_linecount$& is the precise size of the number of newlines in the
+file that has been written (minus one for the blank line between the
+header and the body).
+
+Here is an example of the use of this variable in a DATA ACL:
.code
deny message = Too many lines in message header
condition = \
.code
deny message = Too many lines in message header
condition = \
Fixed developed for diagnosis in bug 927 (which turned out to be
a kernel bug).
Fixed developed for diagnosis in bug 927 (which turned out to be
a kernel bug).
+PP/11 Bugzilla 1055: Update $message_linecount for maildir_tag.
+ Patch from Mark Zealey.
+
Exim version 4.74
-----------------
Exim version 4.74
-----------------
3. Log filenames may now use %M as an escape, instead of %D (still available).
The %M pattern expands to yyyymm, providing month-level resolution.
3. Log filenames may now use %M as an escape, instead of %D (still available).
The %M pattern expands to yyyymm, providing month-level resolution.
+ 4. The $message_linecount variable is now updated for the maildir_tag option,
+ in the same way as $message_size, to reflect the real number of lines,
+ including any header additions or removals from transport.
+
Version 4.74
------------
Version 4.74
------------
uschar **transport_filter_argv = NULL;
int transport_filter_timeout;
BOOL transport_filter_timed_out = FALSE;
uschar **transport_filter_argv = NULL;
int transport_filter_timeout;
BOOL transport_filter_timed_out = FALSE;
extern int timeout_frozen_after; /* Max time to keep frozen messages */
extern BOOL timestamps_utc; /* Use UTC for all times */
extern int transport_count; /* Count of bytes transported */
extern int timeout_frozen_after; /* Max time to keep frozen messages */
extern BOOL timestamps_utc; /* Use UTC for all times */
extern int transport_count; /* Count of bytes transported */
+extern int transport_newlines; /* Accurate count of number of newline chars transported */
extern uschar **transport_filter_argv; /* For on-the-fly filtering */
extern int transport_filter_timeout; /* Timeout for same */
extern BOOL transport_filter_timed_out; /* True if it did */
extern uschar **transport_filter_argv; /* For on-the-fly filtering */
extern int transport_filter_timeout; /* Timeout for same */
extern BOOL transport_filter_timed_out; /* True if it did */
if (use_crlf) *chunk_ptr++ = '\r';
*chunk_ptr++ = '\n';
if (use_crlf) *chunk_ptr++ = '\r';
*chunk_ptr++ = '\n';
/* The check_string test (formerly "from hack") replaces the specific
string at the start of a line with an escape string (e.g. "From " becomes
/* The check_string test (formerly "from hack") replaces the specific
string at the start of a line with an escape string (e.g. "From " becomes
functions. */
transport_count = 0;
functions. */
transport_count = 0;
/* Write any configured prefix text first */
/* Write any configured prefix text first */
if (yield == OK && ob->use_bsmtp)
{
transport_count = 0;
if (yield == OK && ob->use_bsmtp)
{
transport_count = 0;
+ transport_newlines = 0;
if (ob->use_crlf) cr = US"\r";
if (!transport_write_string(fd, "MAIL FROM:<%s>%s\n", return_path, cr))
yield = DEFER;
else
{
address_item *a;
if (ob->use_crlf) cr = US"\r";
if (!transport_write_string(fd, "MAIL FROM:<%s>%s\n", return_path, cr))
yield = DEFER;
else
{
address_item *a;
for (a = addr; a != NULL; a = a->next)
{
address_item *b = testflag(a, af_pfr)? a->parent: a;
if (!transport_write_string(fd, "RCPT TO:<%s>%s\n",
transport_rcpt_address(b, tblock->rcpt_include_affixes), cr))
{ yield = DEFER; break; }
for (a = addr; a != NULL; a = a->next)
{
address_item *b = testflag(a, af_pfr)? a->parent: a;
if (!transport_write_string(fd, "RCPT TO:<%s>%s\n",
transport_rcpt_address(b, tblock->rcpt_include_affixes), cr))
{ yield = DEFER; break; }
}
if (yield == OK && !transport_write_string(fd, "DATA%s\n", cr))
yield = DEFER;
}
if (yield == OK && !transport_write_string(fd, "DATA%s\n", cr))
yield = DEFER;
+ else
+ transport_newlines++;
/* If batch smtp, write the terminating dot. */
/* If batch smtp, write the terminating dot. */
-if (yield == OK && ob->use_bsmtp &&
- !transport_write_string(fd, ".%s\n", cr)) yield = DEFER;
+if (yield == OK && ob->use_bsmtp ) {
+ if(!transport_write_string(fd, ".%s\n", cr)) yield = DEFER;
+ else transport_newlines++;
+}
/* If MBX format is being used, all that writing was to the temporary file.
However, if there was an earlier failure (Exim quota exceeded, for example),
/* If MBX format is being used, all that writing was to the temporary file.
However, if there was an earlier failure (Exim quota exceeded, for example),
if (yield == OK)
{
transport_count = 0; /* Reset transport count for actual write */
if (yield == OK)
{
transport_count = 0; /* Reset transport count for actual write */
+ /* No need to reset transport_newlines as we're just using a block copy
+ * routine so the number won't be affected */
yield = copy_mbx_message(fd, fileno(temp_file), saved_size);
}
else if (errno >= 0) dataname = US"temporary file";
yield = copy_mbx_message(fd, fileno(temp_file), saved_size);
}
else if (errno >= 0) dataname = US"temporary file";
if (yield == OK && !isfifo && EXIMfsync(fd) < 0) yield = DEFER;
if (yield == OK && !isfifo && EXIMfsync(fd) < 0) yield = DEFER;
-/* Update message_size to the accurate count of bytes written, including
-added headers. */
+/* Update message_size and message_linecount to the accurate count of bytes
+written, including added headers. Note; we subtract 1 from message_linecount as
+this variable doesn't count the new line between the header and the body of the
+message. */
message_size = transport_count;
message_size = transport_count;
+message_linecount = transport_newlines - 1;
/* If using a maildir++ quota file, add this message's size to it, and
close the file descriptor, except when the quota has been disabled because we
/* If using a maildir++ quota file, add this message's size to it, and
close the file descriptor, except when the quota has been disabled because we