aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-08-29 11:59:05 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-08-29 12:09:31 +0300
commitc8cfb2268de3da676a77ee07b131174c90f37491 (patch)
treeb619e67a9b6edda70f561869ccad0459ea07215d /src
parent81842febcaa64e068cd978e6a571b2b36fbc3435 (diff)
downloadmailfromd-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.bi108
-rw-r--r--src/builtin/sa.bi6
-rw-r--r--src/prog.c2
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);
diff --git a/src/prog.c b/src/prog.c
index 89482813..ce7cbee3 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.