From: Earl C. <ear...@ya...> - 2012-09-03 22:06:46
|
Per my post in fetchmail-users (https://lists.berlios.de/pipermail/fetchmail-users/2012-September/003231.html) here is a candidate patch to enable additional envelope functionality to better identify the intended recipient in multidrop scenarios. This patch approaches the enhancement in a straightforward way and is relatively unintrusive. Apologies for the tab mangling in this RFC. I can offer up a unmangled version if required to commit the patch. Earl --- fetchmail.h.orig 2012-08-13 13:02:41.000000000 -0700 +++ fetchmail.h 2012-09-03 09:17:37.000000000 -0700 @@ -33,6 +33,7 @@ #endif #include <netdb.h> #include <stdio.h> +#include <regex.h> /* Import Trio if needed */ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) @@ -270,6 +271,7 @@ int interval; /* # cycles to skip between polls */ int authenticate; /* authentication mode to try */ int timeout; /* inactivity timout in seconds */ + regex_t *envre; /* envelope address list header regex */ char *envelope; /* envelope address list header */ int envskip; /* skip to numbered envelope header */ char *qvirtual; /* prefix removed from local user id */ --- transact.c.orig 2012-09-03 11:40:42.000000000 -0700 +++ transact.c 2012-09-03 13:04:12.000000000 -0700 @@ -104,6 +104,88 @@ } } +static int match_envelope(char *hdr, + struct query *ctl) +/** compare the envelope with the RFC822 header and potentially rewrite */ +/** \param hdr RFC822 header in question */ +/** \param ctl envelope */ +{ + static regex_t regex_disabled; + + if (hdr == (char *)NULL || + !ctl->server.envelope || + ctl->server.envelope == STRING_DISABLED) + { + return 0; + } + + if (ctl->server.envelope[0] != '^') + return strncasecmp(ctl->server.envelope, + hdr, strlen(ctl->server.envelope)); + + if (ctl->server.envre == (regex_t*)NULL) + { + int regerr; + + if (outlevel >= O_DEBUG) + report(stdout, + GT_("compiling envelope regexp %s\n"), ctl->server.envelope); + + ctl->server.envre = (regex_t *)xmalloc(sizeof(*ctl->server.envre)); + regerr = regcomp(ctl->server.envre, ctl->server.envelope, REG_EXTENDED); + + if (regerr) + { + report(stderr, + GT_("Error %d compling regex: %s\n"), + regerr, ctl->server.envelope); + + xfree(ctl->server.envre); + ctl->server.envre = ®ex_disabled; + } + } + + if (ctl->server.envre != ®ex_disabled) + { + regmatch_t regmatch[2]; + + int matcherr = regexec(ctl->server.envre, hdr, 2, regmatch, 0); + + if (matcherr == 0) + { + if (regmatch[1].rm_so != -1) + { + int matchlen = regmatch[1].rm_eo - regmatch[1].rm_so; + char *hp = hdr + matchlen + 1; + + memmove(hdr+1, hdr + regmatch[1].rm_so, matchlen); + hdr[0] = ':'; + + while (*hp != '\0' && *hp != '\r' && *hp != '\n') + *hp++ = ' '; + + if (outlevel >= O_DEBUG) + report(stdout, + GT_("extracted envelope address %s\n"), hdr+1); + } + + return 1; + } + + if (matcherr != REG_NOMATCH) + { + char msgbuf[256]; + + regerror(matcherr, ctl->server.envre, msgbuf, sizeof(msgbuf)); + + report(stderr, + GT_("Error matching %s: %s\n"), ctl->server.envelope, msgbuf); + } + } + + return 0; +} + static void find_server_names(const char *hdr, struct query *ctl, struct idlist **xmit_names) @@ -936,9 +1018,7 @@ if (ctl->server.envelope && strcasecmp(ctl->server.envelope, "Received")) { - if (env_offs == -1 && !strncasecmp(ctl->server.envelope, - line, - strlen(ctl->server.envelope))) + if (env_offs == -1 && match_envelope(line, ctl)) { if (skipcount++ < ctl->server.envskip) continue; |