Mercurial > hg > mlmmj
changeset 892:1c13e314e5b9
Handle unfolded header lines better.
author | Ben Schmidt |
---|---|
date | Mon, 03 Feb 2014 00:08:55 +1100 |
parents | 4dd2c703e917 |
children | ba29170a159e |
files | 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 |
diffstat | 9 files changed, 139 insertions(+), 116 deletions(-) [+] |
line wrap: on
line diff
--- a/include/do_all_the_voodoo_here.h Thu Feb 13 09:15:28 2014 +1100 +++ b/include/do_all_the_voodoo_here.h Mon Feb 03 00:08:55 2014 +1100 @@ -26,10 +26,10 @@ #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 */
--- a/include/gethdrline.h Thu Feb 13 09:15:28 2014 +1100 +++ b/include/gethdrline.h Mon Feb 03 00:08:55 2014 +1100 @@ -24,6 +24,6 @@ #ifndef GETHDRLINE_H #define GETHDRLINE_H -char *gethdrline(int fd); +char *gethdrline(int fd,char **unfolded); #endif /* GETHDRLINE_H */
--- a/src/do_all_the_voodoo_here.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/do_all_the_voodoo_here.c Mon Feb 03 00:08:55 2014 +1100 @@ -29,23 +29,21 @@ #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 @@ 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 + } + fsync(outfd); + } 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"); + /* 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; } - - if(writen(outfd, hdrline, strlen(hdrline)) - < 0) { + /* write LF */ + if(writen(outfd, "\n", 1) < 0) { myfree(hdrline); - log_error(LOG_ARGS, - "Error writing hdrs."); + 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 @@ /* 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 @@ 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); @@ -161,14 +157,11 @@ } /* Should it be stripped? */ - if(delhdrs) { - if(!findit(hdrline, delhdrs)) - writen(outfd, hdrline, strlen(hdrline)); - } else - writen(outfd, hdrline, strlen(hdrline)); - + 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 @@ 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");
--- a/src/gethdrline.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/gethdrline.c Mon Feb 03 00:08:55 2014 +1100 @@ -31,52 +31,80 @@ #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; } - /* do not attempt to unfold the end-of-headers marker */ - if (retstr[0] == '\n') - return retstr; + 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; + } 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; + + line = mygetline(fd); + if (!line) return retstr; - oldretstr = retstr; - line = mygetline(fd); - 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(oldretstr); myfree(line); } }
--- a/src/listcontrol.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/listcontrol.c Mon Feb 03 00:08:55 2014 +1100 @@ -33,7 +33,6 @@ #include "mlmmj.h" #include "listcontrol.h" -#include "find_email_adr.h" #include "getlistdelim.h" #include "strgen.h" #include "prepstdreply.h"
--- a/src/mlmmj-bounce.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/mlmmj-bounce.c Mon Feb 03 00:08:55 2014 +1100 @@ -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 @@ 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); + /* 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); - } else { - addr = NULL; + } } myfree(line); - return addr; + break; } } myfree(line); } - return NULL; + return addr; } static void print_help(const char *prg)
--- a/src/mlmmj-process.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/mlmmj-process.c Mon Feb 03 00:08:55 2014 +1100 @@ -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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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;
--- a/src/mlmmj-send.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/mlmmj-send.c Mon Feb 03 00:08:55 2014 +1100 @@ -844,7 +844,6 @@ } verp = ctrlvalue(listdir, "verp"); - chomp(verp); if(verp == NULL) if(statctrl(listdir, "verp") == 1) verp = mystrdup(""); @@ -993,7 +992,6 @@ if(!relayhost) { relayhost = ctrlvalue(listdir, "relayhost"); - chomp(relayhost); } if(!relayhost) strncpy(relay, RELAYHOST, sizeof(relay));
--- a/src/send_digest.c Thu Feb 13 09:15:28 2014 +1100 +++ b/src/send_digest.c Mon Feb 03 00:08:55 2014 +1100 @@ -44,7 +44,6 @@ #include "gethdrline.h" #include "statctrl.h" #include "unistr.h" -#include "chomp.h" struct mail { @@ -119,18 +118,14 @@ subj = NULL; from = NULL; - while ((line = gethdrline(archivefd))) { - if (strcmp(line, "\n") == 0) { - myfree(line); - break; + while ((line = gethdrline(archivefd, NULL))) { + if (strncasecmp(line, "Subject:", 8) == 0) { + myfree(subj); + subj = unistr_header_to_utf8(line + 8); } - if (strncasecmp(line, "Subject: ", 9) == 0) { - myfree(subj); - subj = unistr_header_to_utf8(line + 9); - } - 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 @@ 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);