]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Handle unfolded header lines better.
authorBen Schmidt <none@none>
Sun, 2 Feb 2014 13:08:55 +0000 (00:08 +1100)
committerBen Schmidt <none@none>
Sun, 2 Feb 2014 13:08:55 +0000 (00:08 +1100)
--HG--
extra : rebase_source : dc2fc081a837b35f6058d4bc3665f642595a115d

include/do_all_the_voodoo_here.h
include/gethdrline.h
src/do_all_the_voodoo_here.c
src/gethdrline.c
src/listcontrol.c
src/mlmmj-bounce.c
src/mlmmj-process.c
src/mlmmj-send.c
src/send_digest.c

index 62fc5ecfa2f54f90119bd105a417304d371f32b4..a9850c714a22256aa05cb39a6f141a5fad9bb394 100644 (file)
 
 #include "mlmmj.h" /* For struct mailhdr and struct strlist */
 
-int findit(const char *line, const char **headers);
+int findit(const char *line, const struct strlist *headers);
 void getinfo(const char *line, struct mailhdr *readhdrs);
 int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
-             const char **delhdrs, struct mailhdr *readhdrs,
+             const struct strlist *delhdrs, struct mailhdr *readhdrs,
              struct strlist *allhdrs, const char *subjectprefix);
 
 #endif /* DO_ALL_THE_VOODOO_HERE_H */
index 1cb5ed432b035eb9b5bf89a2a8e007c3c3c52679..434ed5e1e2b19eeb6ef81572dd95aef946cda2be 100644 (file)
@@ -24,6 +24,6 @@
 #ifndef GETHDRLINE_H
 #define GETHDRLINE_H
 
-char *gethdrline(int fd);
+char *gethdrline(int fd,char **unfolded);
 
 #endif /* GETHDRLINE_H */
index 679e276b0154fe1ae1212a0a82ddbe7c57fcd239..020ac07362cc13305355f42c6d2b1ac7ed8451b1 100644 (file)
 #include "mygetline.h"
 #include "gethdrline.h"
 #include "strgen.h"
-#include "chomp.h"
 #include "ctrlvalue.h"
 #include "do_all_the_voodoo_here.h"
 #include "log_error.h"
 #include "wrappers.h"
 #include "memory.h"
 
-int findit(const char *line, const char **headers)
+int findit(const char *line, const struct strlist *headers)
 {
-       int i = 0;
+       int i;
        size_t len;
 
-       while(headers[i]) {
-               len = strlen(headers[i]);
-               if(strncasecmp(line, headers[i], len) == 0)
+       for (i=0;i<headers->count;i++) {
+               len = strlen(headers->strs[i]);
+               if(strncasecmp(line, headers->strs[i], len) == 0)
                        return 1;
-               i++;
        }
 
        return 0;
@@ -54,80 +52,79 @@ int findit(const char *line, const char **headers)
 void getinfo(const char *line, struct mailhdr *readhdrs)
 {
        int i = 0;
-       size_t tokenlen, linelen, valuelen;
+       size_t tokenlen, valuelen;
 
        while(readhdrs[i].token) {
                tokenlen = strlen(readhdrs[i].token);
-               linelen = strlen(line);
                if(strncasecmp(line, readhdrs[i].token, tokenlen) == 0) {
                        readhdrs[i].valuecount++;
-                       valuelen = linelen - tokenlen + 1;
+                       valuelen = strlen(line) - tokenlen;
                        readhdrs[i].values =
                                (char **)myrealloc(readhdrs[i].values,
                                  readhdrs[i].valuecount * sizeof(char *));
                        readhdrs[i].values[readhdrs[i].valuecount - 1] =
                                        (char *)mymalloc(valuelen + 1);
-                       strncpy(readhdrs[i].values[readhdrs[i].valuecount - 1],
-                                               line+tokenlen, valuelen);
-                       chomp(readhdrs[i].values[readhdrs[i].valuecount - 1]);
+                       strcpy(readhdrs[i].values[readhdrs[i].valuecount - 1],
+                                               line+tokenlen);
                }
                i++;
        }
 }
 
 int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
-                const char **delhdrs, struct mailhdr *readhdrs,
+                const struct strlist *delhdrs, struct mailhdr *readhdrs,
                 struct strlist *allhdrs, const char *prefix)
 {
-       char *hdrline, *subject, *unqp;
+       char *hdrline, *unfolded, *subject, *unqp;
        int hdrsadded = 0;
        int subject_present = 0;
 
        allhdrs->count = 0;
        allhdrs->strs = NULL;
 
-       while((hdrline = gethdrline(infd))) {
-               /* Done with headers? Then add extra if wanted*/
-               if((strncasecmp(hdrline, "mime", 4) == 0) ||
-                       ((strlen(hdrline) == 1) && (hdrline[0] == '\n'))){
+       for(;;) {
+               hdrline = gethdrline(infd, &unfolded);
 
-                       /* add extra headers */
-                       if(!hdrsadded && hdrfd >= 0) {
+               /* add extra headers before MIME* headers,
+                  or after all headers */
+               if(!hdrsadded &&
+                               (hdrline == NULL ||
+                                strncasecmp(hdrline, "mime", 4) == 0)) {
+                       if(hdrfd >= 0) {
                                if(dumpfd2fd(hdrfd, outfd) < 0) {
                                        log_error(LOG_ARGS, "Could not "
                                                "add extra headers");
                                        myfree(hdrline);
+                                       myfree(unfolded);
                                        return -1;
-                               } else
-                                       hdrsadded = 1;
-                       }
-                       
-                       fsync(outfd);
-
-                       /* end of headers, write single LF */ 
-                       if(hdrline[0] == '\n') {
-                               /* but first add Subject if none is present
-                                * and a prefix is defined */
-                               if (prefix && !subject_present)
-                               {
-                                       subject = concatstr(3, "Subject: ", 
-                                                               prefix, "\n");
-                                       writen(outfd, subject, strlen(subject));
-                                       myfree(subject);
-                                       subject_present = 1;
                                }
+                               fsync(outfd);
+                       }
+                       hdrsadded = 1;
+               }
 
-                               if(writen(outfd, hdrline, strlen(hdrline))
-                                               < 0) {
-                                       myfree(hdrline);
-                                       log_error(LOG_ARGS,
-                                                       "Error writing hdrs.");
-                                       return -1;
-                               }
+               /* end of headers */ 
+               if(hdrline == NULL) {
+                       /* add Subject if none is present
+                          and a prefix is defined */
+                       if (prefix && !subject_present) {
+                               subject = concatstr(3,"Subject: ",prefix,"\n");
+                               writen(outfd, subject, strlen(subject));
+                               myfree(subject);
+                               subject_present = 1;
+                       }
+                       /* write LF */
+                       if(writen(outfd, "\n", 1) < 0) {
                                myfree(hdrline);
-                               break;
+                               myfree(unfolded);
+                               log_error(LOG_ARGS, "Error writing hdrs.");
+                               return -1;
                        }
+                       myfree(hdrline);
+                       myfree(unfolded);
+                       break;
                }
+
                /* Do we want info from hdrs? Get it before it's gone */
                if(readhdrs)
                        getinfo(hdrline, readhdrs);
@@ -135,9 +132,8 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                /* Snatch a copy of the header */
                allhdrs->count++;
                allhdrs->strs = myrealloc(allhdrs->strs,
-                                       sizeof(char *) * (allhdrs->count + 1));
+                                       sizeof(char *) * (allhdrs->count));
                allhdrs->strs[allhdrs->count-1] = mystrdup(hdrline);
-               allhdrs->strs[allhdrs->count] = NULL;  /* XXX why, why, why? */
 
                /* Add Subject: prefix if wanted */
                if(prefix) {
@@ -146,9 +142,9 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                                unqp = cleanquotedp(hdrline + 8);
                                if(strstr(hdrline + 8, prefix) == NULL &&
                                   strstr(unqp, prefix) == NULL) {
-                                       subject = concatstr(3,
+                                       subject = concatstr(4,
                                                        "Subject: ", prefix,
-                                                       hdrline + 8);
+                                                       hdrline + 8, "\n");
                                        writen(outfd, subject,
                                                        strlen(subject));
                                        myfree(subject);
@@ -159,16 +155,13 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                                myfree(unqp);
                        }
                }
-               
-               /* Should it be stripped? */
-               if(delhdrs) {
-                       if(!findit(hdrline, delhdrs))
-                               writen(outfd, hdrline, strlen(hdrline));
-               } else
-                       writen(outfd, hdrline, strlen(hdrline));
 
+               /* Should it be stripped? */
+               if(!delhdrs || !findit(hdrline, delhdrs))
+                       writen(outfd, unfolded, strlen(unfolded));
 
                myfree(hdrline);
+               myfree(unfolded);
        }
 
        /* Just print the rest of the mail */
@@ -177,7 +170,7 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                return -1;
        }
 
-       /* No more, lets add the footer if one */
+       /* No more, let's add the footer if one */
        if(footfd >= 0)
                if(dumpfd2fd(footfd, outfd) < 0) {
                        log_error(LOG_ARGS, "Error when adding footer");
index dcbddf543c26e1871d35d5024c67a0321d83fa85..5dc7dc5c0d1d7381b9dc83da3d93fe8b9607417f 100644 (file)
 #include "memory.h"
 #include "wrappers.h"
 #include "log_error.h"
+#include "chomp.h"
 
 
-char *gethdrline(int fd)
+char *gethdrline(int fd, char **unfolded)
 {
-       char *line = NULL, *retstr = NULL, *oldretstr = NULL;
+       char *line = NULL, *retstr = NULL, *oldretstr = NULL, *oldunfolded = NULL;
        char ch;
        ssize_t n;
-       
+
        retstr = mygetline(fd);
        if (!retstr) {
+               if (unfolded != NULL)
+                       *unfolded = NULL;
+               return NULL;
+       }
+
+       if (unfolded != NULL)
+               *unfolded = mystrdup(retstr);
+
+       chomp(retstr);
+
+       /* end-of-headers */
+       if (*retstr == '\0') {
+               if (unfolded != NULL) {
+                       myfree(*unfolded);
+                       *unfolded = NULL;
+               }
+               myfree(retstr);
                return NULL;
        }
 
-       /* do not attempt to unfold the end-of-headers marker */
-       if (retstr[0] == '\n')
-               return retstr;
-       
        for(;;) {
-               /* look-ahead one char to determine if we need to unfold */
+               /* look ahead one char to determine if we need to fold */
                n = readn(fd, &ch, 1);
                if (n == 0) {  /* end of file, and therefore also headers */
                        return retstr;
                } else if (n == -1) {  /* error */
                        log_error(LOG_ARGS, "readn() failed in gethdrline()");
+                       if (unfolded != NULL) {
+                               myfree(*unfolded);
+                               *unfolded = NULL;
+                       }
                        myfree(retstr);
                        return NULL;
                }
 
                if (lseek(fd, -1, SEEK_CUR) == (off_t)-1) {
                        log_error(LOG_ARGS, "lseek() failed in gethdrline()");
+                       if (unfolded != NULL) {
+                               myfree(*unfolded);
+                               *unfolded = NULL;
+                       }
                        myfree(retstr);
                        return NULL;
                }
 
-               if ((ch != '\t') && (ch != ' '))  /* no more unfolding */
+               if ((ch != '\t') && (ch != ' '))  /* no more folding */
                        return retstr;
 
-               oldretstr = retstr;
                line = mygetline(fd);
-               if (!line) {
+               if (!line)
                        return retstr;
+
+               if (unfolded != NULL) {
+                       oldunfolded = *unfolded;
+                       *unfolded = concatstr(2, oldunfolded, line);
+                       myfree(oldunfolded);
                }
 
+               chomp(line);
+               oldretstr = retstr;
                retstr = concatstr(2, oldretstr, line);
-               
                myfree(oldretstr);
+
                myfree(line);
        }
 }
index 58c22c5567ee3a65bb6a10f2a6c1b3bbe4beb16a..d0c2e14e83f0cef78c635e1deed484fb24f9282b 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "mlmmj.h"
 #include "listcontrol.h"
-#include "find_email_adr.h"
 #include "getlistdelim.h"
 #include "strgen.h"
 #include "prepstdreply.h"
index 9f9630a6faa69a15af41c59a71251abee1d3b4b7..8525a0fc20949d3c7bac1e21c2baabecfebe8254 100644 (file)
@@ -43,7 +43,6 @@
 #include "log_error.h"
 #include "subscriberfuncs.h"
 #include "mygetline.h"
-#include "chomp.h"
 #include "prepstdreply.h"
 #include "memory.h"
 #include "find_email_adr.h"
@@ -136,34 +135,38 @@ char *dsnparseaddr(const char *mailname)
                return NULL;
        }
 
-       while((line = gethdrline(fd))) {
+       while((line = gethdrline(fd, NULL))) {
                linedup = mystrdup(line);
                for(i = 0; line[i]; i++)
                        linedup[i] = tolower(line[i]);
                search = strstr(linedup, "message/delivery-status");
                myfree(linedup);
-               if(search)
+               if(search) {
                        indsn = 1;
+                       myfree(line);
+                       continue;
+               }
                if(indsn) {
-                       i = strncasecmp(line, "Final-Recipient:", 16);
-                       if(i == 0) {
-                               find_email_adr(line, &emails);
-                               if(emails.emailcount > 0) {
-                                       addr = mystrdup(emails.emaillist[0]);
-                                       for(i = 0; i < emails.emailcount; i++)
-                                               myfree(emails.emaillist[i]);
-                                       myfree(emails.emaillist);
-                               } else {
-                                       addr = NULL;
+                       /* TODO: this parsing could be greatly improved */
+                       if(strncasecmp(line, "Final-Recipient:", 16)) {
+                               search = strstr(line, ";");
+                               if (search) {
+                                       find_email_adr(search+1, &emails);
+                                       if(emails.emailcount > 0) {
+                                               addr = mystrdup(emails.emaillist[0]);
+                                               for(i = 0; i < emails.emailcount; i++)
+                                                       myfree(emails.emaillist[i]);
+                                               myfree(emails.emaillist);
+                                       }
                                }
                                myfree(line);
-                               return addr;
+                               break;
                        }
                }
                myfree(line);
        }
 
-       return NULL;
+       return addr;
 }
 
 static void print_help(const char *prg)
index 08ec978565a9352babdcff0cab55a73439af1a7f..7ca25c2d2792ede075a87764352b2503a90977cd 100644 (file)
@@ -51,7 +51,6 @@
 #include "subscriberfuncs.h"
 #include "memory.h"
 #include "log_oper.h"
-#include "chomp.h"
 #include "unistr.h"
 
 enum action {
@@ -345,7 +344,6 @@ static enum action do_access(struct strlist *rule_strs, struct strlist *hdrs,
                if (match != not) {
                        if (match) {
                                hdr = mystrdup(hdrs->strs[j]);
-                               chomp(hdr);
                                log_oper(listdir, OPLOGFNAME, "mlmmj-process: access -"
                                                " A mail from \"%s\" with header \"%s\" was %s by"
                                                " rule #%d \"%s\"", from, hdr, action_strs[act],
@@ -555,15 +553,14 @@ int main(int argc, char **argv)
        }
 
        delheaders->strs = myrealloc(delheaders->strs,
-                       (delheaders->count+3) * sizeof(char *));
+                       (delheaders->count+2) * sizeof(char *));
        delheaders->strs[delheaders->count++] = mystrdup("From ");
        delheaders->strs[delheaders->count++] = mystrdup("Return-Path:");
-       delheaders->strs[delheaders->count] = NULL;
 
        subjectprefix = ctrlvalue(listdir, "prefix");
 
        if(do_all_the_voodoo_here(rawmailfd, donemailfd, hdrfd, footfd,
-                               (const char**)delheaders->strs, readhdrs,
+                               delheaders, readhdrs,
                                &allheaders, subjectprefix) < 0) {
                log_error(LOG_ARGS, "Error in do_all_the_voodoo_here");
                exit(EXIT_FAILURE);
@@ -688,12 +685,11 @@ int main(int argc, char **argv)
                        delheaders->count = 0;
                        delheaders->strs = NULL;
                        delheaders->strs = myrealloc(delheaders->strs,
-                               (delheaders->count+3) * sizeof(char *));
+                                       2 * sizeof(char *));
                        delheaders->strs[delheaders->count++] =
                                mystrdup("From ");
                        delheaders->strs[delheaders->count++] =
                                mystrdup("Return-Path:");
-                       delheaders->strs[delheaders->count] = NULL;
                        if((rawmailfd = open(mailfile, O_RDONLY)) < 0) {
                                log_error(LOG_ARGS, "could not open() "
                                                    "input mail file");
@@ -706,11 +702,14 @@ int main(int argc, char **argv)
                                exit(EXIT_FAILURE);
                        }
                        if(do_all_the_voodoo_here(rawmailfd, donemailfd, -1,
-                                       -1, (const char**)delheaders->strs,
+                                       -1, delheaders,
                                        NULL, &allheaders, NULL) < 0) {
                                log_error(LOG_ARGS, "do_all_the_voodoo_here");
                                exit(EXIT_FAILURE);
                        }
+                       for(i = 0; i < delheaders->count; i++)
+                               myfree(delheaders->strs[i]);
+                       myfree(delheaders->strs);
                        close(rawmailfd);
                        close(donemailfd);
                        unlink(mailfile);
@@ -828,7 +827,6 @@ int main(int argc, char **argv)
                        log_error(LOG_ARGS, "Found To: %s",
                                toemails.emaillist[i]);
                        for(j = 0; j < alternates->count; j++) {
-                               chomp(alternates->strs[j]);
                                if(strcasecmp(alternates->strs[j],
                                        toemails.emaillist[i]) == 0)
                                        intocc = 1;
@@ -839,7 +837,6 @@ int main(int argc, char **argv)
                        log_error(LOG_ARGS, "Found Cc: %s",
                                ccemails.emaillist[i]);
                        for(j = 0; j < alternates->count; j++) {
-                               chomp(alternates->strs[j]);
                                if(strcasecmp(alternates->strs[j],
                                        ccemails.emaillist[i]) == 0)
                                        intocc = 1;
index 1e52ab980b16348fc039b2708cb27de71f25f669..5ba1acc3b837b0c1008d2251267e961e8705d262 100644 (file)
@@ -844,7 +844,6 @@ int main(int argc, char **argv)
        }
 
        verp = ctrlvalue(listdir, "verp");
-       chomp(verp);
        if(verp == NULL)
                if(statctrl(listdir, "verp") == 1)
                        verp = mystrdup("");
@@ -993,7 +992,6 @@ int main(int argc, char **argv)
 
        if(!relayhost) {
                relayhost = ctrlvalue(listdir, "relayhost");
-               chomp(relayhost);
        }
        if(!relayhost)
                strncpy(relay, RELAYHOST, sizeof(relay));
index 4314e3755242a32b5d8d76a1eaf0ecaff4745983..99e20348d13336bb64e25bc1008427ab2a9c3d43 100644 (file)
@@ -44,7 +44,6 @@
 #include "gethdrline.h"
 #include "statctrl.h"
 #include "unistr.h"
-#include "chomp.h"
 
 
 struct mail {
@@ -119,18 +118,14 @@ static void rewind_thread_list(void * state)
                subj = NULL;
                from = NULL;
 
-               while ((line = gethdrline(archivefd))) {
-                       if (strcmp(line, "\n") == 0) {
-                               myfree(line);
-                               break;
-                       }
-                       if (strncasecmp(line, "Subject: ", 9) == 0) {
+               while ((line = gethdrline(archivefd, NULL))) {
+                       if (strncasecmp(line, "Subject:", 8) == 0) {
                                myfree(subj);
-                               subj = unistr_header_to_utf8(line + 9);
+                               subj = unistr_header_to_utf8(line + 8);
                        }
-                       if (strncasecmp(line, "From: ", 6) == 0) {
+                       if (strncasecmp(line, "From:", 5) == 0) {
                                myfree(from);
-                               from = unistr_header_to_utf8(line + 6);
+                               from = unistr_header_to_utf8(line + 5);
                        }
                        myfree(line);
                }
@@ -174,12 +169,22 @@ static void rewind_thread_list(void * state)
                        thread_idx = num_threads-1;
                }
 
+               tmp = from;
+               for (;;) {
+                       if (isspace(*tmp)) {
+                               tmp++;
+                               continue;
+                       }
+                       break;
+               }
+               /* tmp is now left-trimmed from */
+
                threads[thread_idx].num_mails++;
                threads[thread_idx].mails = myrealloc(threads[thread_idx].mails,
                                threads[thread_idx].num_mails*sizeof(struct mail));
                threads[thread_idx].mails[threads[thread_idx].num_mails-1].idx = i;
                threads[thread_idx].mails[threads[thread_idx].num_mails-1].from =
-                               concatstr(5, "      ", buf, " - ", from, "\n");
+                               concatstr(5, "      ", buf, " - ", tmp, "\n");
 
                myfree(subj);
                myfree(from);