diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-08-29 11:59:05 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-08-29 12:09:31 +0300 |
commit | c8cfb2268de3da676a77ee07b131174c90f37491 (patch) | |
tree | b619e67a9b6edda70f561869ccad0459ea07215d /src | |
parent | 81842febcaa64e068cd978e6a571b2b36fbc3435 (diff) | |
download | mailfromd-c8cfb2268de3da676a77ee07b131174c90f37491.tar.gz mailfromd-c8cfb2268de3da676a77ee07b131174c90f37491.tar.bz2 |
Improve error handling in message_burst.
* mflib/status.mf (BURST_ERR_FAIL)
(BURST_ERR_IGNORE,BURST_ERR_BODY): New constants.
* src/builtin/burst.bi (burst_stream) <on_bad_format>: New member.
(finish_stream): If the stream cannot be converted to message,
use on_bad_format to decide what to do with it.
(message_burst): Take optional argument.
* src/builtin/sa.bi (set_xscript): Now returns void.
* src/prog.c (env_function_cleanup_del): Bugfix.
* NEWS, doc/functions.texi: Document the changes to message_burst.
Diffstat (limited to 'src')
-rw-r--r-- | src/builtin/burst.bi | 108 | ||||
-rw-r--r-- | src/builtin/sa.bi | 6 | ||||
-rw-r--r-- | src/prog.c | 2 |
3 files changed, 101 insertions, 15 deletions
diff --git a/src/builtin/burst.bi b/src/builtin/burst.bi index 99baa674..65c2a2f9 100644 --- a/src/builtin/burst.bi +++ b/src/builtin/burst.bi @@ -225,21 +225,109 @@ struct burst_stream { mu_stream_t stream; /* Output stream */ int flags; /* See F_ flags above */ size_t partno; /* Number of the part within the message */ + int on_bad_format; }; +static void +_cleanup_message(void *ptr) +{ + mu_message_t msg = ptr; + mu_message_destroy(&msg, mu_message_get_owner(msg)); +} + +static void +_cleanup_header(void *ptr) +{ + mu_header_t hdr = ptr; + mu_header_destroy(&hdr); +} + +static void +_cleanup_body(void *ptr) +{ + mu_body_t body = ptr; + mu_body_destroy(&body, mu_body_get_owner(body)); +} + +static mu_message_t +create_temp_message(eval_environ_t env, mu_stream_t stream) +{ + int rc; + mu_header_t hdr; + mu_body_t body; + mu_message_t msg; + + MF_ASSERT(mu_message_create(&msg, NULL) == 0, + mfe_failure, + "mu_message_create: %s", + mu_strerror(rc)); + MF_DCL_CLEANUP(msg, _cleanup_message); + + MF_ASSERT(mu_header_create(&hdr, "\n", 1) == 0, + mfe_failure, + "mu_header_create: %s", + mu_strerror(rc)); + MF_DCL_CLEANUP(hdr, _cleanup_header); + + MF_ASSERT(mu_body_create(&body, msg) == 0, + mfe_failure, + "mu_body_create: %s", + mu_strerror(rc)); + MF_DCL_CLEANUP(body, _cleanup_body); + + /* FIXME: MU: mu_body_set_stream does not change stream's refcount */ + MF_ASSERT(mu_body_set_stream(body, stream, msg) == 0, + mfe_failure, + "mu_body_set_stream: %s", + mu_strerror(rc)); + + mu_message_set_header (msg, hdr, NULL); + mu_message_set_body (msg, body, NULL); + + MF_CLR_CLEANUP(msg); + MF_CLR_CLEANUP(hdr); + MF_CLR_CLEANUP(body); + return msg; +} + +#define BURST_ERR_FAIL 0 +#define BURST_ERR_IGNORE 1 +#define BURST_ERR_BODY 2 + static inline void finish_stream(eval_environ_t env, struct burst_stream *bs) { if (bs->stream) { + int rc; mu_message_t msg; + bs->flags &= ~F_FIRST; mu_stream_seek(bs->stream, 0, SEEK_SET, NULL); - msg = MF_STREAM_TO_MESSAGE(bs->stream); + rc = mu_stream_to_message(bs->stream, &msg); + if (rc == MU_ERR_BAD_822_FORMAT) { + switch (bs->on_bad_format) { + case BURST_ERR_FAIL: + MF_THROW(mfe_failure, + "mu_stream_to_message: %s", + mu_strerror (rc)); + + case BURST_ERR_IGNORE: + mu_stream_unref(bs->stream); + bs->stream = 0; + return; + + case BURST_ERR_BODY: + msg = create_temp_message(env, bs->stream); + } + } else + MF_ASSERT(rc == 0, + mfe_failure, + "mu_stream_to_message: %s", + mu_strerror(rc)); mu_mime_add_part(bs->mime, msg); mu_message_unref(msg); bs->stream = 0; bs->partno++; - bs->flags &= ~F_FIRST; } } @@ -282,11 +370,10 @@ burst_stream_cleanup(void *data) } /* Burst an RFC 934 digest. Return 0 if OK, 1 if the message is not - a valid digest. - FIXME: On errors, cleanup and return -1. -*/ + a valid digest. */ int -burst_digest(eval_environ_t env, mu_mime_t mime, mu_message_t msg) +burst_digest(eval_environ_t env, mu_mime_t mime, mu_message_t msg, + int onbadfmt) { int rc; mu_body_t body; @@ -307,6 +394,7 @@ burst_digest(eval_environ_t env, mu_mime_t mime, mu_message_t msg) bs->stream = NULL; bs->flags = F_FIRST; bs->partno = 1; + bs->on_bad_format = onbadfmt; MF_DCL_CLEANUP(bs, burst_stream_cleanup); rc = mu_message_get_body(msg, &body); @@ -383,7 +471,7 @@ burst_digest(eval_environ_t env, mu_mime_t mime, mu_message_t msg) return result; } -MF_DEFUN(message_burst, NUMBER, NUMBER nmsg) +MF_DEFUN(message_burst, NUMBER, NUMBER nmsg, OPTIONAL, NUMBER onbadfmt) { int rc; mu_message_t msg; @@ -393,9 +481,9 @@ MF_DEFUN(message_burst, NUMBER, NUMBER nmsg) rc = mu_mime_create(&mime, NULL, 0); MF_ASSERT(rc == 0, mfe_failure, - _("mu_mime_create: %s"), + "mu_mime_create: %s", mu_strerror(rc)); - rc = burst_digest(env, mime, msg); + rc = burst_digest(env, mime, msg, MF_OPTVAL(onbadfmt, BURST_ERR_FAIL)); MF_ASSERT(rc == 0, mfe_format, _("message is not a RFC-934 digest")); @@ -403,7 +491,7 @@ MF_DEFUN(message_burst, NUMBER, NUMBER nmsg) mu_mime_unref(mime); MF_ASSERT(rc == 0, mfe_failure, - _("mu_mime_get_message: %s"), + "mu_mime_get_message: %s", mu_strerror(rc)); rc = bi_message_register(env, NULL, msg, MF_MSG_STANDALONE); if (rc < 0) { diff --git a/src/builtin/sa.bi b/src/builtin/sa.bi index d4b823e8..0fd16f61 100644 --- a/src/builtin/sa.bi +++ b/src/builtin/sa.bi @@ -32,10 +32,9 @@ MF_VAR(sa_threshold, NUMBER); MF_VAR(sa_keywords, STRING); MF_VAR(clamav_virus_name, STRING); -static int +static void set_xscript(mu_stream_t *pstr) { - int rc; mu_stream_t tstr = *pstr; if (mu_debug_level_p(debug_handle, MU_DEBUG_PROT)) { @@ -58,7 +57,6 @@ set_xscript(mu_stream_t *pstr) mu_stream_unref(tstr); } } - return rc; } static int @@ -373,7 +371,7 @@ MF_DEFUN(spamc, NUMBER, NUMBER nmsg, STRING urlstr, NUMBER prec, NUMBER command) break; default: MF_THROW(mfe_failure, - "unknown flag: %ld", command); + _("unknown command: %ld"), command); } mu_stream_printf(ostr, "%s SPAMC/1.2\n", cmdstr); @@ -455,7 +455,7 @@ env_function_cleanup_del(eval_environ_t env, void *ptr) clos.data = ptr; - rc = mu_list_locate(env->cleanup_list, &clos, (void**)cptr); + rc = mu_list_locate(env->cleanup_list, &clos, (void**)&cptr); if (rc == 0) { cptr->cleanup = NULL; mu_list_remove(env->cleanup_list, &clos); |