#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 */
#ifndef GETHDRLINE_H
#define GETHDRLINE_H
-char *gethdrline(int fd);
+char *gethdrline(int fd,char **unfolded);
#endif /* GETHDRLINE_H */
#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;
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);
/* 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) {
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);
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 */
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");
#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);
}
}
#include "mlmmj.h"
#include "listcontrol.h"
-#include "find_email_adr.h"
#include "getlistdelim.h"
#include "strgen.h"
#include "prepstdreply.h"
#include "log_error.h"
#include "subscriberfuncs.h"
#include "mygetline.h"
-#include "chomp.h"
#include "prepstdreply.h"
#include "memory.h"
#include "find_email_adr.h"
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)
#include "subscriberfuncs.h"
#include "memory.h"
#include "log_oper.h"
-#include "chomp.h"
#include "unistr.h"
enum action {
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],
}
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);
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");
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);
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;
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;
}
verp = ctrlvalue(listdir, "verp");
- chomp(verp);
if(verp == NULL)
if(statctrl(listdir, "verp") == 1)
verp = mystrdup("");
if(!relayhost) {
relayhost = ctrlvalue(listdir, "relayhost");
- chomp(relayhost);
}
if(!relayhost)
strncpy(relay, RELAYHOST, sizeof(relay));
#include "gethdrline.h"
#include "statctrl.h"
#include "unistr.h"
-#include "chomp.h"
struct mail {
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);
}
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);