Mercurial > hg > mlmmj
changeset 568:99f493df54af
Add support for qmail (envelope from address in environment variable)
author | mortenp |
---|---|
date | Mon, 04 Sep 2006 08:04:12 +1000 |
parents | baffb3e41df7 |
children | 0ce85f30f3bb |
files | ChangeLog include/listcontrol.h src/listcontrol.c src/mlmmj-process.c |
diffstat | 4 files changed, 107 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Sep 04 07:52:44 2006 +1000 +++ b/ChangeLog Mon Sep 04 08:04:12 2006 +1000 @@ -1,3 +1,4 @@ + o Add support for qmail (envelope from address in environment variable) o Add digest text part o Add subscriber moderation o Fix default subject in administrative mails
--- a/include/listcontrol.h Mon Sep 04 07:52:44 2006 +1000 +++ b/include/listcontrol.h Mon Sep 04 08:04:12 2006 +1000 @@ -27,7 +27,7 @@ #include "find_email_adr.h" int listcontrol(struct email_container *fromemails, const char *listdir, - const char *controladdr, const char *mlmmjsub, + const char *controlstr, const char *mlmmjsub, const char *mlmmjunsub, const char *mlmmjsend, const char *mlmmjbounce, const char *mailname);
--- a/src/listcontrol.c Mon Sep 04 07:52:44 2006 +1000 +++ b/src/listcontrol.c Mon Sep 04 08:04:12 2006 +1000 @@ -98,15 +98,14 @@ int listcontrol(struct email_container *fromemails, const char *listdir, - const char *controladdr, const char *mlmmjsub, + const char *controlstr, const char *mlmmjsub, const char *mlmmjunsub, const char *mlmmjsend, const char *mlmmjbounce, const char *mailname) { - char *atsign, *recipdelimsign, *listdelim, *bouncenr, *tmpstr; - char *controlstr, *param = NULL, *conffilename, *moderatefilename; + char *bouncenr, *tmpstr; + char *param = NULL, *conffilename, *moderatefilename; char *c, *archivefilename, *sendfilename; const char *subswitch; - size_t len; struct stat stbuf; int closedlist, nosubconfirm, tmpfd, noget, i, closedlistsub, subonlyget = 0; @@ -127,18 +126,6 @@ else subswitch = "-C"; - listdelim = getlistdelim(listdir); - recipdelimsign = strstr(controladdr, listdelim); - MY_ASSERT(recipdelimsign); - atsign = index(controladdr, '@'); - MY_ASSERT(atsign); - len = atsign - recipdelimsign; - - controlstr = mymalloc(len); - MY_ASSERT(controlstr); - snprintf(controlstr, len, "%s", recipdelimsign + strlen(listdelim)); - myfree(listdelim); - #if 0 log_error(LOG_ARGS, "controlstr = [%s]\n", controlstr); log_error(LOG_ARGS, "fromemails->emaillist[0] = [%s]\n", @@ -182,7 +169,6 @@ param = NULL; } - myfree(controlstr); break; }
--- a/src/mlmmj-process.c Mon Sep 04 07:52:44 2006 +1000 +++ b/src/mlmmj-process.c Mon Sep 04 08:04:12 2006 +1000 @@ -299,6 +299,38 @@ } +static char *recipient_extra(const char *listdir, const char *addr) +{ + char *listdelim; + char *delim, *atsign, *ret; + size_t len; + + if (!addr) + return NULL; + + listdelim = getlistdelim(listdir); + + delim = strstr(addr, listdelim); + if (!delim) { + myfree(listdelim); + return NULL; + } + delim += strlen(listdelim); + myfree(listdelim); + + atsign = strrchr(delim, '@'); + if (!atsign) + return NULL; + + len = atsign - delim; + ret = (char *)mymalloc(len + 1); + strncpy(ret, delim, len); + ret[len] = '\0'; + + return ret; +} + + static void print_help(const char *prg) { printf("Usage: %s -L /path/to/list -m /path/to/mail [-h] [-P] [-V]\n" @@ -323,16 +355,16 @@ char *mlmmjsend, *mlmmjsub, *mlmmjunsub, *mlmmjbounce; char *bindir, *subjectprefix, *discardname, *listaddr, *listdelim; char *listfqdn, *listname, *fromaddr; - char *queuefilename, *recipextra, *owner = NULL; + char *queuefilename, *recipextra = NULL, *owner = NULL; char *maildata[2] = { "posteraddr", NULL }; + char *envstr, *efrom; struct stat st; uid_t uid; struct email_container fromemails = { 0, NULL }; struct email_container toemails = { 0, NULL }; struct email_container ccemails = { 0, NULL }; - struct email_container efromemails = { 0, NULL }; - struct email_container dtoemails = { 0, NULL }; - struct email_container *whichto; + struct email_container rpemails = { 0, NULL }; + struct email_container dtemails = { 0, NULL }; struct strlist *access_rules = NULL; struct strlist *delheaders = NULL; struct strlist allheaders; @@ -473,60 +505,77 @@ if(footfd >= 0) close(footfd); - if(readhdrs[0].token) { /* From: addresses */ + /* From: addresses */ for(i = 0; i < readhdrs[0].valuecount; i++) { find_email_adr(readhdrs[0].values[i], &fromemails); } - } - if(readhdrs[1].token) { /* To: addresses */ + /* To: addresses */ for(i = 0; i < readhdrs[1].valuecount; i++) { find_email_adr(readhdrs[1].values[i], &toemails); } - } - if(readhdrs[2].token) { /* Cc: addresses */ + /* Cc: addresses */ for(i = 0; i < readhdrs[2].valuecount; i++) { find_email_adr(readhdrs[2].values[i], &ccemails); } + + /* Return-Path: addresses */ + for(i = 0; i < readhdrs[3].valuecount; i++) { + find_email_adr(readhdrs[3].values[i], &rpemails); } - if(readhdrs[3].token) { /* Return-Path: (envelope from) */ - for(i = 0; i < readhdrs[3].valuecount; i++) { - find_email_adr(readhdrs[3].values[i], &efromemails); - } - if(efromemails.emailcount == 0) { - efromemails.emaillist = - (char **)mymalloc(sizeof(char *)); - efromemails.emaillist[0] = mystrdup("<>"); - } + /* Delivered-To: addresses */ + for(i = 0; i < readhdrs[4].valuecount; i++) { + find_email_adr(readhdrs[4].values[i], &dtemails); } - if(readhdrs[4].token) { /* Delivered-To: (envelope to) */ - for(i = 0; i < readhdrs[4].valuecount; i++) { - find_email_adr(readhdrs[4].values[i], &dtoemails); - } + /* envelope from */ + if((envstr = getenv("SENDER")) != NULL) { + /* qmail, postfix, exim */ + efrom = mystrdup(envstr); + } else if(rpemails.emailcount >= 1) { + /* the (first) Return-Path: header */ + efrom = mystrdup(rpemails.emaillist[0]); + } else { + efrom = mystrdup(""); } - if(dtoemails.emaillist) - whichto = &dtoemails; - else if(toemails.emaillist) - whichto = &toemails; - else - whichto = NULL; - + /* address extension (the "foo" part of "user+foo@domain.tld") */ + if((envstr = getenv("EXT")) != NULL) { + /* qmail */ + recipextra = mystrdup(envstr); + } else if((envstr = getenv("EXTENSION")) != NULL) { + /* postfix */ + recipextra = mystrdup(envstr); + } else if((envstr = getenv("LOCAL_PART_SUFFIX")) != NULL) { + /* exim */ listdelim = getlistdelim(listdir); - if(whichto && whichto->emaillist && whichto->emaillist[0]){ - recipextra = strstr(whichto->emaillist[0], listdelim); - if (recipextra) - recipextra += strlen(listdelim); - } else + if (strncmp(envstr, listdelim, strlen(listdelim)) == 0) { + recipextra = mystrdup(envstr + strlen(listdelim)); + } else { + recipextra = mystrdup(envstr); + } + myfree(listdelim); + } else if(dtemails.emailcount >= 1) { + /* parse the (first) Delivered-To: header */ + recipextra = recipient_extra(listdir, dtemails.emaillist[0]); + } else if(toemails.emailcount >= 1) { + /* parse the (first) To: header */ + recipextra = recipient_extra(listdir, toemails.emaillist[0]); + } else { recipextra = NULL; - myfree(listdelim); + } + if(recipextra && (strlen(recipextra) == 0)) { + myfree(recipextra); + recipextra = NULL; + } + + /* Why is this here, and not in listcontrol() ? -- mortenp 20060409 */ if(recipextra) { owner = concatstr(2, listdir, "/control/owner"); - if(owner && strncmp(recipextra, "owner@", 6) == 0) { + if(owner && strcmp(recipextra, "owner") == 0) { /* strip envelope from before resending */ delheaders->count = 0; delheaders->strs = NULL; @@ -559,11 +608,11 @@ unlink(mailfile); log_oper(listdir, OPLOGFNAME, "mlmmj-recieve: sending" " mail from %s to owner", - efromemails.emaillist[0]); + efrom); execlp(mlmmjsend, mlmmjsend, "-l", "4", "-L", listdir, - "-F", efromemails.emaillist[0], + "-F", efrom, "-s", owner, "-a", "-m", donemailname, (char *)NULL); @@ -575,7 +624,7 @@ log_error(LOG_ARGS, "listcontrol(from, %s, %s, %s, %s, %s, %s)\n", listdir, toemails.emaillist[0], mlmmjsub, mlmmjunsub, mlmmjsend, mlmmjbounce); #endif unlink(mailfile); - listcontrol(&fromemails, listdir, whichto->emaillist[0], + listcontrol(&fromemails, listdir, recipextra, mlmmjsub, mlmmjunsub, mlmmjsend, mlmmjbounce, donemailname); @@ -605,14 +654,14 @@ myfree(delheaders); - if(efromemails.emailcount != 1) { /* don't send mails with <> in From + if(strcmp(efrom, "") == 0) { /* don't send mails with <> in From to the list */ discardname = concatstr(3, listdir, "/queue/discarded/", randomstr); - log_error(LOG_ARGS, "Discarding %s due to invalid envelope" - " from email count (was %d, must be 1)", - mailfile, efromemails.emailcount); + errno = 0; + log_error(LOG_ARGS, "Discarding %s due to missing envelope" + " from address", mailfile); rename(mailfile, discardname); unlink(donemailname); myfree(donemailname);