diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-18 10:53:19 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-18 14:07:03 +0300 |
commit | efc22fc1c0eb1b851b2a61227662ad372bcc1fda (patch) | |
tree | 4ad0024f4f869d7224033218c61d60dd78055366 /mfd/prog.c | |
parent | 8e51f4c4bcffd7e1610e237eb2be2cb2e9d978e6 (diff) | |
download | mailfromd-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.c | 78 |
1 files changed, 63 insertions, 15 deletions
@@ -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 |