]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Add support for qmail (envelope from address in environment variable)
authormortenp <none@none>
Sun, 3 Sep 2006 22:04:12 +0000 (08:04 +1000)
committermortenp <none@none>
Sun, 3 Sep 2006 22:04:12 +0000 (08:04 +1000)
ChangeLog
include/listcontrol.h
src/listcontrol.c
src/mlmmj-process.c

index 83edc94d9a29c00c16132a5daf8a906fcc011ac0..c4f176028bb8f7111c0e37134dae8867668deca7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 92bb6e0ad147d93732fc4dca6ca52c72101fbd19..5cc9a227b460bad7e8de09e7cbf56b7e05195f4b 100644 (file)
@@ -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);
 
index cae701b64b05a6442ddc91fdb8352ad565f96946..dce0c25ca7cfc38d7e8e35688ffc2be320394977 100644 (file)
@@ -98,15 +98,14 @@ static struct ctrl_command ctrl_commands[] = {
 
 
 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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
        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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                param = NULL;
                        }
 
-                       myfree(controlstr);
                        break;
 
                }
index de3a6c8150a78a449f773c571ca6d400c9944858..e6b5b12856950871da738c7006a760aa9ae60f37 100644 (file)
@@ -299,6 +299,38 @@ static enum action do_access(struct strlist *rule_strs, struct strlist *hdrs)
 }
 
 
+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 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
        if(footfd >= 0)
                close(footfd);
 
-       if(readhdrs[0].token) { /* From: addresses */
-               for(i = 0; i < readhdrs[0].valuecount; i++) {
-                       find_email_adr(readhdrs[0].values[i], &fromemails);
-               }
+       /* From: addresses */
+       for(i = 0; i < readhdrs[0].valuecount; i++) {
+               find_email_adr(readhdrs[0].values[i], &fromemails);
        }
 
-       if(readhdrs[1].token) { /* To: addresses */
-               for(i = 0; i < readhdrs[1].valuecount; i++) {
-                       find_email_adr(readhdrs[1].values[i], &toemails);
-               }
+       /* To: addresses */
+       for(i = 0; i < readhdrs[1].valuecount; i++) {
+               find_email_adr(readhdrs[1].values[i], &toemails);
        }
 
-       if(readhdrs[2].token) { /* Cc: addresses */
-               for(i = 0; i < readhdrs[2].valuecount; i++) {
-                       find_email_adr(readhdrs[2].values[i], &ccemails);
-               }
+       /* Cc: addresses */
+       for(i = 0; i < readhdrs[2].valuecount; i++) {
+               find_email_adr(readhdrs[2].values[i], &ccemails);
        }
 
-       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("<>");
-               }
+       /* Return-Path: addresses */
+       for(i = 0; i < readhdrs[3].valuecount; i++) {
+               find_email_adr(readhdrs[3].values[i], &rpemails);
        }
 
-       if(readhdrs[4].token) { /* Delivered-To: (envelope to) */
-               for(i = 0; i < readhdrs[4].valuecount; i++) {
-                       find_email_adr(readhdrs[4].values[i], &dtoemails);
-               }
+       /* Delivered-To: addresses */
+       for(i = 0; i < readhdrs[4].valuecount; i++) {
+               find_email_adr(readhdrs[4].values[i], &dtemails);
        }
 
-       if(dtoemails.emaillist)
-               whichto = &dtoemails;
-       else if(toemails.emaillist)
-               whichto = &toemails;
-       else
-               whichto = NULL;
+       /* 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("");
+       }
 
-       listdelim = getlistdelim(listdir);
-       if(whichto && whichto->emaillist && whichto->emaillist[0]){
-               recipextra = strstr(whichto->emaillist[0], listdelim);
-               if (recipextra)
-                       recipextra += strlen(listdelim);
-       } else
+       /* 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 (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 @@ int main(int argc, char **argv)
                        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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
 
        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);