From 78580a2cbc33444df649d998ae710bcd7e507ec7 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 14 Dec 2008 00:06:38 +0100 Subject: [PATCH] Vacation: added support for properly updating references header. --- Makefile.am | 1 + TODO | 2 - src/lib-sieve/plugins/enotify/ntfy-mailto.c | 1 - src/lib-sieve/plugins/vacation/cmd-vacation.c | 26 ++++++++++-- src/lib-sieve/rfc2822.c | 40 +++++++++++++++++++ src/lib-sieve/rfc2822.h | 3 ++ tests/extensions/vacation/references.sieve | 4 ++ tests/extensions/vacation/references.svtest | 18 +++++++++ 8 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 tests/extensions/vacation/references.sieve create mode 100644 tests/extensions/vacation/references.svtest diff --git a/Makefile.am b/Makefile.am index c5794b9a7..832e2806e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,6 +78,7 @@ test_cases = \ tests/extensions/subaddress/rfc.svtest \ tests/extensions/vacation/errors.svtest \ tests/extensions/vacation/execute.svtest \ + tests/extensions/vacation/references.svtest \ $(ENOTIFY_TESTS) if HAVE_DOVECOT_LIBS diff --git a/TODO b/TODO index 6a901579d..4fab9cc72 100644 --- a/TODO +++ b/TODO @@ -18,8 +18,6 @@ Next (in order of descending priority/precedence): any vacation response that is generated. UTF-8 characters can be used in the string argument; implementations MUST convert the string to [RFC2047] encoded words if and only if non-ASCII characters are present. - - Vacation: properly implement construction of a References header from - the original message. - Body: contains various issues that need to be resolved for standards compliance. Body test support currently matches but barely exceeds the original CMU Sieve implentation in terms of standards compliance. diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c index 927b116d0..360a64b37 100644 --- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c +++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c @@ -423,7 +423,6 @@ static bool ntfy_mailto_action_execute (const struct sieve_action_exec_env *aenv, const struct sieve_enotify_context *nctx) { - const struct sieve_message_data *msgdata = aenv->msgdata; const struct sieve_script_env *senv = aenv->scriptenv; struct ntfy_mailto_context *mtctx = (struct ntfy_mailto_context *) nctx->method_context; diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index d1b1dc5da..b07d581c0 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -2,6 +2,8 @@ */ #include "lib.h" +#include "str.h" +#include "strfuncs.h" #include "md5.h" #include "hostpid.h" #include "str-sanitize.h" @@ -9,6 +11,8 @@ #include "message-date.h" #include "ioloop.h" +#include "rfc2822.h" + #include "sieve-common.h" #include "sieve-code.h" #include "sieve-address.h" @@ -796,6 +800,9 @@ static bool act_vacation_send void *smtp_handle; FILE *f; const char *outmsgid; + const char *const *headers; + string_t *out = t_str_new(256); + int references; /* Check smpt functions just to be sure */ @@ -820,12 +827,25 @@ static bool act_vacation_send fprintf(f, "To: <%s>\r\n", msgdata->return_path); fprintf(f, "Subject: %s\r\n", str_sanitize(ctx->subject, 80)); - + + references = mail_get_headers_utf8 + (aenv->msgdata->mail, "references", &headers); + if ( msgdata->id != NULL ) { fprintf(f, "In-Reply-To: %s\r\n", msgdata->id); - - /* FIXME: Update References header */ + + if ( references >= 0 ) + rfc2822_header_add_folded + (out, "References", t_strconcat(headers[0], " ", msgdata->id, NULL)); + else + rfc2822_header_add_folded(out, "References", msgdata->id); + + fwrite(str_c(out), str_len(out), 1, f); + } else if ( references > 0 ) { + rfc2822_header_add_folded(out, "References", headers[0]); + fwrite(str_c(out), str_len(out), 1, f); } + fprintf(f, "Auto-Submitted: auto-replied (vacation)\r\n"); fprintf(f, "X-Sieve: %s\r\n", SIEVE_IMPLEMENTATION); diff --git a/src/lib-sieve/rfc2822.c b/src/lib-sieve/rfc2822.c index 329432a6c..8f30b746e 100644 --- a/src/lib-sieve/rfc2822.c +++ b/src/lib-sieve/rfc2822.c @@ -2,9 +2,12 @@ */ #include "lib.h" +#include "str.h" #include "rfc2822.h" +#include <ctype.h> + /* NOTE: much of the functionality implemented here should eventually appear * somewhere in Dovecot itself. */ @@ -31,3 +34,40 @@ bool rfc2822_header_field_name_verify return TRUE; } +void rfc2822_header_add_folded +(string_t *out, const char *name, const char *body) +{ + const char *sp = body, *bp = body, *wp; + unsigned int len = str_len(out); + + /* Add properly formatted header field name first */ + str_append_c(out, i_toupper(name[0])); + str_append(out, t_str_lcase(name+1)); + + /* Add separating colon */ + str_append(out, ": "); + + /* Add folded field body */ + len = str_len(out) - len; + while ( *bp != '\0' ) { + while ( *bp != '\0' && (wp == NULL || len < 80) ) { + if ( *bp == ' ' || *bp == '\t' ) + wp = bp; + + bp++; len++; + } + + if ( *bp == '\0' ) break; + + str_append_n(out, sp, wp-sp); + str_append(out, "\r\n"); + + len = bp - wp; + sp = wp; + wp = NULL; + } + + str_append_n(out, sp, bp-sp); + str_append(out, "\r\n"); +} + diff --git a/src/lib-sieve/rfc2822.h b/src/lib-sieve/rfc2822.h index 3748c950f..b16e65522 100644 --- a/src/lib-sieve/rfc2822.h +++ b/src/lib-sieve/rfc2822.h @@ -9,4 +9,7 @@ bool rfc2822_header_field_name_verify (const char *field_name, unsigned int len); +void rfc2822_header_add_folded + (string_t *out, const char *name, const char *body); + #endif /* __RFC2822_H */ diff --git a/tests/extensions/vacation/references.sieve b/tests/extensions/vacation/references.sieve new file mode 100644 index 000000000..77658f2fa --- /dev/null +++ b/tests/extensions/vacation/references.sieve @@ -0,0 +1,4 @@ +require "vacation"; + +vacation "I am on vacation."; +discard; diff --git a/tests/extensions/vacation/references.svtest b/tests/extensions/vacation/references.svtest new file mode 100644 index 000000000..f67b1e696 --- /dev/null +++ b/tests/extensions/vacation/references.svtest @@ -0,0 +1,18 @@ +require "vnd.dovecot.testsuite"; +require "vacation"; + +test_set "message" text: +From: stephan@rename-it.nl +Subject: frop +References: <1234@local.machine.example> <3456@example.net> + <435444@ttms.com> <4223@froop.nl> <m345444444@message-id.exp> +Message-ID: <432df324@rename-it.nl> +To: nico@vestingbar.nl + +Frop +. +; + +test "References" { + vacation "I am not in today!"; +} -- GitLab