aboutsummaryrefslogtreecommitdiff
path: root/mfd/prog.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-04-18 10:53:19 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-04-18 14:07:03 +0300
commitefc22fc1c0eb1b851b2a61227662ad372bcc1fda (patch)
tree4ad0024f4f869d7224033218c61d60dd78055366 /mfd/prog.c
parent8e51f4c4bcffd7e1610e237eb2be2cb2e9d978e6 (diff)
downloadmailfromd-efc22fc1c0eb1b851b2a61227662ad372bcc1fda.tar.gz
mailfromd-efc22fc1c0eb1b851b2a61227662ad372bcc1fda.tar.bz2
Fix CRLF/LF inconsistencies. Fix bug in SAVEEX/RESTEX.
* mfd/prog.c (instr_restex): Bugfix. Use pop to restore catch addresses. This also fixes the resulting tos value. * mfd/bi_body.m4 (current_message): Use mf_stream_to_message * mfd/bi_sa.m4 (spamd_send_stream): Return int. Recode delimiters to "\r\n". (sa): Check return from spamd_send_stream. Adjust reported stream size. (clamav): Check return from spamd_send_stream. * mfd/bi_sieve.m4 [MAILUTILS_VERSION_NUMBER < 1290]: Remove * mfd/mailfromd.h (env_get_line_count, mf_stream_to_message): New functions. * mfd/prog.c (struct eval_environ.line_count): New member. (env_get_line_count): New function. (env_capture_start): Init eval_environ.line_count (env_capture_write): Recode "\r\n" -> "\r". Update eval_environ.line_count. * mtasim/mtasim.c (send_body): New function. (smtp): Use CRLF as line terminator in message body. * pmult/pmult.c (collect_headers): strip off \r's.
Diffstat (limited to 'mfd/prog.c')
-rw-r--r--mfd/prog.c78
1 files changed, 63 insertions, 15 deletions
diff --git a/mfd/prog.c b/mfd/prog.c
index 73ffffc7..de0a3a51 100644
--- a/mfd/prog.c
+++ b/mfd/prog.c
@@ -1,5 +1,5 @@
/* This file is part of Mailfromd.
- Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff
+ Copyright (C) 2006, 2007, 2008, 2009 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -279,6 +279,7 @@ struct eval_environ {
char *string; /* Last matched string */
mu_stream_t stream; /* Capture stream */
+ size_t line_count; /* Number of lines in stream */
/* Non-local exits */
prog_counter_t defcatch[mf_exception_count];
@@ -1674,10 +1675,9 @@ instr_saveex(eval_environ_t env)
if (PROG_TRACE_ENGINE)
prog_trace(env, "SAVEEX %x", exmask);
push(env, (STKVAL) exmask);
- for (i = 0; i < mf_exception_count; i++) {
+ for (i = 0; i < mf_exception_count; i++)
if (EXMASK(i) & exmask)
push(env, (STKVAL) env->catch[i]);
- }
}
void
@@ -1694,11 +1694,9 @@ instr_restex(eval_environ_t env)
if (PROG_TRACE_ENGINE)
prog_trace(env, "RESTEX %x", exmask);
- for (i = 0; i < mf_exception_count; i++) {
+ for (i = mf_exception_count-1; i >= 0; i--)
if (EXMASK(i) & exmask)
- env->catch[i] = (prog_counter_t)
- env->dataseg[env->base-i-1];
- }
+ env->catch[i] = (prog_counter_t) pop(env);
}
void
@@ -2098,13 +2096,31 @@ env_get_context(eval_environ_t env)
return env->ctx;
}
+size_t
+env_get_line_count(eval_environ_t env)
+{
+ return env->line_count;
+}
+
-/* Capturing support */
+/* Capturing support:
+
+ Captured message is stored in env->stream. Before storing, any
+ CRs (\r) are removed from the message. (FIXME: Actually, only
+ those CRs should be removed that are followed by LF. However,
+ that should not be a problem, since no CRs are allowed in RFC822
+ messages, unless followed by LF. Anyway, I'll fix that soon.)
+
+ The number of lines in stream is stored in env->line_count. It is
+ used to produce correct message size for functions that need it,
+ e.g. bi_sa.
+ */
int
env_capture_start(eval_environ_t env)
{
int rc;
+ env->line_count = 0;
if (env->stream) {
/* Drop any previously registered current message */
bi_drop_current_message(env);
@@ -2114,7 +2130,7 @@ env_capture_start(eval_environ_t env)
rc = mu_stream_truncate(env->stream, 0);
if (rc == 0 && mu_stream_seek(env->stream, 0, SEEK_SET) == 0)
return 0;
-
+
/* If truncate fails, try to re-create the stream */
mu_stream_close(env->stream);
mu_stream_destroy(&env->stream,
@@ -2137,22 +2153,54 @@ env_capture_start(eval_environ_t env)
}
return 0;
}
-
+
+static void
+env_capture_count_lines(eval_environ_t env, const char *buf, size_t size)
+{
+ while (size) {
+ size_t len;
+ const char *p = memchr(buf, '\n', size);
+ if (p) {
+ env->line_count++;
+ len = p - buf + 1;
+ } else
+ len = size;
+ buf += len;
+ size -= len;
+ }
+}
+
int
env_capture_write(eval_environ_t env, const char *buf, size_t size)
{
- if (env->stream) {
- int rc = mu_stream_sequential_write(env->stream, buf, size);
+ if (!env->stream)
+ return 1;
+
+ env_capture_count_lines(env, buf, size);
+ while (size) {
+ int rc;
+ size_t len;
+ const char *p = memchr(buf, '\r', size);
+ if (p)
+ len = p - buf;
+ else
+ len = size;
+ rc = mu_stream_sequential_write(env->stream, buf, len);
if (rc) {
mu_error(_("%sTemporary stream write failed: %s"),
- mailfromd_msgid(env->ctx), mu_strerror(rc));
+ mailfromd_msgid(env->ctx),
+ mu_strerror(rc));
mu_stream_close(env->stream);
mu_stream_destroy(&env->stream,
mu_stream_get_owner(env->stream));
+ return rc;
}
- return rc;
+ if (p)
+ len++;
+ buf += len;
+ size -= len;
}
- return 1;
+ return 0;
}
int

Return to:

Send suggestions and report system problems to the System administrator.