From 06814960e7a88a661537d2fa1d1b607f3e48f363 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 21 Aug 2016 10:07:01 +0200 Subject: [PATCH 3/5] make it possible to change headers after editing the body of the message This patch looks at certain paramters after an E-Mail message is edited and makes it possible to adapt the from header based on certain conditions or the from lines. Example: send2-hook '! ~C problems@' 'clr_header reply-to:' send2-hook '~C problems@' 'set_header reply-to: problems' send2-hook '! ~C @lhsystems.com' 'set_header from: Thomas Glanzmann ' send2-hook '~C @lhsystems.com | ~C @tomorrow-focus.de' 'set_header from: Thomas Glanzmann ' --- hook.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ init.h | 4 ++++ mutt.h | 6 +++++ protos.h | 1 + 4 files changed, 90 insertions(+) diff --git a/hook.c b/hook.c index 1b906c3..823164c 100644 --- a/hook.c +++ b/hook.c @@ -42,6 +42,82 @@ typedef struct hook static HOOK *Hooks = NULL; static int current_hook_type = 0; +static ENVELOPE *current_hook_env = NULL; + +int mutt_modify_header (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + size_t keylen; + char *p; + ADDRESS **c = NULL; + + + mutt_extract_token (buf, s, MUTT_TOKEN_SPACE | MUTT_TOKEN_QUOTE); + if ((p = strpbrk (buf->data, ": \t")) == NULL || *p != ':') + { + strfcpy (err->data, _("invalid header field"), err->dsize); + return (-1); + } + + keylen = p - buf->data + 1; + + if (current_hook_env == NULL) { + strfcpy (err->data, _("not called inside a hook"), err->dsize); + return (-1); + } + + if (ascii_strncasecmp (buf->data, "reply-to:", 9) == 0) { + c = &(current_hook_env->reply_to); + + } else if (ascii_strncasecmp (buf->data, "from:", 5) == 0) { + c = &(current_hook_env->from); + + } else { + strfcpy (err->data, _("can't handle this heaer"), err->dsize); + return -1; + } + + switch(data) { + case MODIFYHEADER_ADD: + /* FIXME: check if already there --tg 17:37 05-05-12 */ + *c = rfc822_parse_adrlist (*c, buf->data + keylen); + break; + + case MODIFYHEADER_CLR: + rfc822_free_address (c); + break; + + case MODIFYHEADER_DEL: +#if 0 + { + ADDRESS *t = *c; + while(t) { + if (ascii_strncasecmp (buf->data + keylen, t->mailbox, + mutt_strlen(buf->data + keylen)) == 0) { + } + + rfc822_free_address (c); + } + } +#else + strfcpy (err->data, _("not implemented"), err->dsize); + return -1; +#endif + break; + + case MODIFYHEADER_SET: + rfc822_free_address (c); + *c = rfc822_parse_adrlist (*c, buf->data + keylen); + break; + + default: + strfcpy (err->data, _("can only add, del or set header"), err->dsize); + return -1; + break; + } + + memset (buf, 0, sizeof (BUFFER)); + return 0; +} int mutt_parse_hook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { @@ -350,6 +426,7 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) HOOK *hook; current_hook_type = type; + current_hook_env = hdr->env; mutt_buffer_init (&err); err.dsize = STRING; @@ -368,6 +445,7 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) mutt_error ("%s", err.data); mutt_sleep (1); current_hook_type = 0; + current_hook_env = NULL; FREE (&err.data); return; @@ -377,6 +455,7 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) FREE (&err.data); current_hook_type = 0; + current_hook_env = NULL; } static int diff --git a/init.h b/init.h index 3f3f96d..d809281 100644 --- a/init.h +++ b/init.h @@ -3877,6 +3877,7 @@ struct command_t }; const struct command_t Commands[] = { + { "add_header", mutt_modify_header, MODIFYHEADER_ADD }, { "alternates", parse_alternates, 0 }, { "unalternates", parse_unalternates, 0 }, #ifdef USE_SOCKET @@ -3889,10 +3890,12 @@ const struct command_t Commands[] = { { "alternative_order", parse_list, UL &AlternativeOrderList}, { "bind", mutt_parse_bind, 0 }, { "charset-hook", mutt_parse_hook, MUTT_CHARSETHOOK }, + { "clr_header", mutt_modify_header, MODIFYHEADER_CLR }, #ifdef HAVE_COLOR { "color", mutt_parse_color, 0 }, { "uncolor", mutt_parse_uncolor, 0 }, #endif + { "del_header", mutt_modify_header, MODIFYHEADER_DEL }, { "exec", mutt_parse_exec, 0 }, { "fcc-hook", mutt_parse_hook, MUTT_FCCHOOK }, { "fcc-save-hook", mutt_parse_hook, MUTT_FCCHOOK | MUTT_SAVEHOOK }, @@ -3932,6 +3935,7 @@ const struct command_t Commands[] = { { "source", parse_source, 0 }, { "spam", parse_spam_list, MUTT_SPAM }, { "nospam", parse_spam_list, MUTT_NOSPAM }, + { "set_header", mutt_modify_header, MODIFYHEADER_SET }, { "subscribe", parse_subscribe, 0 }, { "toggle", parse_set, MUTT_SET_INV }, { "unalias", parse_unalias, 0 }, diff --git a/mutt.h b/mutt.h index 2cf55b1..1575d5d 100644 --- a/mutt.h +++ b/mutt.h @@ -313,6 +313,12 @@ enum #define MUTT_SPAM 1 #define MUTT_NOSPAM 2 +/* flags for mutt_modify_header */ +#define MODIFYHEADER_ADD (1<<0) +#define MODIFYHEADER_CLR (1<<1) +#define MODIFYHEADER_DEL (1<<2) +#define MODIFYHEADER_SET (1<<3) + /* boolean vars */ enum { diff --git a/protos.h b/protos.h index c543b04..91a134b 100644 --- a/protos.h +++ b/protos.h @@ -328,6 +328,7 @@ int mutt_match_rx_list (const char *, RX_LIST *); int mutt_match_spam_list (const char *, SPAM_LIST *, char *, int); int mutt_messages_in_thread (CONTEXT *, HEADER *, int); int mutt_multi_choice (char *prompt, char *letters); +int mutt_modify_header (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err); int mutt_needs_mailcap (BODY *); int mutt_num_postponed (int); int mutt_parse_bind (BUFFER *, BUFFER *, unsigned long, BUFFER *); -- 2.1.4