summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-25 20:54:43 -0400
committerSam Varshavchik2013-08-28 21:07:40 -0400
commit9bb1a8d85390653f702e8ad5556a2cd3793acbfe (patch)
tree2aafb33608ec6c69182e00364d324f845a3e7325
parent2ec3d0c52bff3e27242ae214571792c5f2d5299a (diff)
downloadcourier-libs-9bb1a8d85390653f702e8ad5556a2cd3793acbfe.tar.bz2
maildrop: rfc2045-parse message when reading it initially.
At startup MIME parse the message. maildrop no longer ignores leading blank lines, and From_ line. Use reformail -f0 to filter the message for maildrop, if that's the case. Get rid of msgoffset (starting offset of the message). rfc2045-parse the message as maildrop reads it.
-rw-r--r--maildrop/Makefile.am1
-rw-r--r--maildrop/main.C10
-rw-r--r--maildrop/message.C53
-rw-r--r--maildrop/message.h13
-rw-r--r--maildrop/messageinfo.C53
-rw-r--r--maildrop/messageinfo.h9
-rw-r--r--maildrop/mio.C7
-rw-r--r--maildrop/mio.h5
8 files changed, 107 insertions, 44 deletions
diff --git a/maildrop/Makefile.am b/maildrop/Makefile.am
index 8ebe6c1..f256edd 100644
--- a/maildrop/Makefile.am
+++ b/maildrop/Makefile.am
@@ -27,6 +27,7 @@ libmdcommon_la_SOURCES=alarm.C alarm.h alarmsleep.C alarmsleep.h alarmtimer.C \
funcs.h maildrop.C maildrop.h mio.C mio.h setgroupid.c setgroupid.h \
tempfile.C tempfile.h
libmdcommon_la_LIBADD=../maildir/libmaildir.la \
+ ../rfc2045/librfc2045.la \
../rfc822/librfc822.la \
../unicode/libunicode.la \
../numlib/libnumlib.la ../liblock/liblock.la \
diff --git a/maildrop/main.C b/maildrop/main.C
index 9d281eb..d144263 100644
--- a/maildrop/main.C
+++ b/maildrop/main.C
@@ -41,6 +41,12 @@
extern "C" int gethostname(const char *, size_t);
#endif
+void rfc2045_error(const char *p)
+{
+ fprintf(stderr, "%s\n", p);
+ fflush(stderr);
+ exit(1);
+}
extern void setprocgroup();
@@ -765,9 +771,7 @@ Buffer msg;
if (VerboseLevel() > 1)
{
msg.reset();
- msg.append("Message start at ");
- msg.append((unsigned long)maildrop.msginfo.msgoffset);
- msg.append(" bytes, envelope sender=");
+ msg.append("Message envelope sender=");
if (maildrop.msginfo.fromname.Length() > 0)
msg += maildrop.msginfo.fromname;
msg.append("\n");
diff --git a/maildrop/message.C b/maildrop/message.C
index a02f170..d583fbe 100644
--- a/maildrop/message.C
+++ b/maildrop/message.C
@@ -5,10 +5,41 @@
#include "funcs.h"
#include "varlist.h"
+static int rfc2045_seek_func(off_t pos, void *arg)
+{
+ Message *p=reinterpret_cast<Message *>(arg);
+
+ p->seek(pos);
+ return 0;
+}
+
+static ssize_t rfc2045_read_func(char *buf, size_t cnt, void *arg)
+{
+ Message *p=reinterpret_cast<Message *>(arg);
+
+ ssize_t n=0;
+
+ while (cnt)
+ {
+ int c=p->get_c();
+
+ if (c < 0)
+ return -1;
+ *buf++=c;
+ --cnt;
+ ++n;
+ }
+ return n;
+}
Message::Message() : buffer(0), bufptr(0),
- extra_headers(0), extra_headersptr(0), msgsize(0)
+ extra_headers(0), extra_headersptr(0), msgsize(0),
+ rfc2045src_parser(rfc2045src()),
+ rfc2045p(0)
{
+ rfc2045src_parser.seek_func=rfc2045_seek_func;
+ rfc2045src_parser.read_func=rfc2045_read_func;
+ rfc2045src_parser.arg=reinterpret_cast<void *>(this);
}
Message::~Message()
@@ -16,6 +47,8 @@ Message::~Message()
mio.fd(-1); // Either way, it's not our file
if (buffer) delete[] buffer;
if (extra_headers) delete[] extra_headers;
+ if (rfc2045p)
+ rfc2045_free(rfc2045p);
}
void Message::Init()
@@ -30,11 +63,14 @@ void Message::Init()
delete[] extra_headers;
extra_headers=0;
}
+ if (rfc2045p)
+ rfc2045_free(rfc2045p);
extra_headersptr=0;
msgsize=0;
msglines=0;
tempfile.Close();
mio.fd(-1);
+ rfc2045p=rfc2045_alloc();
}
void Message::Init(int fd)
@@ -57,13 +93,14 @@ void Message::Init(int fd)
if (fd < 0) throw "dup() failed.";
mio.fd(fd);
+ mio.rfc2045p=rfc2045p;
if (mio.Rewind() < 0) seekerr();
int c;
while ((c=mio.get()) >= 0)
if (c == '\n') msglines++;
-
+ mio.rfc2045p=0;
return;
}
// Well, just read the message, and let Init() figure out what to
@@ -75,12 +112,15 @@ void Message::Init(int fd)
#ifdef BUFSIZ
char buf[BUFSIZ];
#else
-char buf[512];
+char buf[8192];
#endif
int n;
while ((n=read(fd, buf, sizeof(buf))) > 0)
+ {
+ rfc2045_parse(rfc2045p, buf, n);
Init(buf, n);
+ }
if (n < 0)
throw "Error - read() failed reading message.";
#if CRLF_TERM
@@ -183,13 +223,6 @@ void Message::Rewind()
{
RewindIgnore();
-off_t n=maildrop.msginfo.msgoffset;
-
- while (n)
- {
- (void)get_c();
- --n;
- }
extra_headersptr=extra_headers;
if (extra_headersptr && !*extra_headersptr)
extra_headersptr=0;
diff --git a/maildrop/message.h b/maildrop/message.h
index 0f6a5ee..a539929 100644
--- a/maildrop/message.h
+++ b/maildrop/message.h
@@ -1,6 +1,7 @@
#ifndef message_h
#define message_h
+#include "rfc2045/rfc2045.h"
//////////////////////////////////////////////////////////////////////////////
//
@@ -75,7 +76,12 @@ public:
off_t MessageSize();
off_t MessageLines() { return (msglines); }
void setmsgsize();
- } ;
+
+ // API translator for rfc2045 functions
+
+ struct rfc2045src rfc2045src_parser;
+ struct rfc2045 *rfc2045p;
+} ;
#include "funcs.h"
#include "maildrop.h"
@@ -134,7 +140,7 @@ off_t pos;
pos=mio.tell();
if (pos == -1) seekerr();
}
- pos -= maildrop.msginfo.msgoffset;
+
if (extra_headersptr)
pos += extra_headersptr-extra_headers;
else
@@ -158,8 +164,6 @@ int l=0;
extra_headersptr=0;
n -= l;
}
- n += maildrop.msginfo.msgoffset;
-
if (mio.fd() >= 0)
{
if (mio.seek(n, SEEK_SET) < 0) seekerr();
@@ -174,7 +178,6 @@ int l=0;
inline off_t Message::MessageSize()
{
off_t s=msgsize;
- s -= maildrop.msginfo.msgoffset;
if (extra_headers)
s += strlen(extra_headers);
diff --git a/maildrop/messageinfo.C b/maildrop/messageinfo.C
index 9f1b203..a7c339e 100644
--- a/maildrop/messageinfo.C
+++ b/maildrop/messageinfo.C
@@ -1,24 +1,23 @@
#include "config.h"
#include "messageinfo.h"
#include "message.h"
-
+#include <ctype.h>
void MessageInfo::info(Message &msg)
{
Buffer buf;
-off_t msgstart=0;
- msgoffset=0;
msg.Rewind();
- fromname.reset();
+ fromname.set("MAILER-DAEMON");
+
for (;;)
{
- msgstart=msg.tell();
buf.reset();
if (msg.appendline(buf) < 0) return;
- int l=buf.Length();
- const char *p=buf;
+ int l=buf.Length();
+
+ const char *p=buf;
if (l && p[l-1] == '\n')
{
@@ -26,20 +25,40 @@ off_t msgstart=0;
buf.Length(l);
}
- if (l == 0) continue;
+ if (l == 0) break;
+
+ p=buf;
+ if (strncasecmp(p, "Return-Path:", 12))
+ continue;
- if (l < 5) break;
- if (p[0] == 'F' && p[1] == 'r' && p[2] == 'o' && p[3] == 'm'
- && p[4] == ' ')
+ p += 12;
+ l -= 12;
+
+ while (*p && *p != '\n' && isspace(*p) && l)
{
+ ++p;
+ --l;
+ }
+
+ if (l && *p == '<')
+ {
+ ++p;
+ --l;
+ }
+
int i;
- for (i=5; i<l; i++)
- if (p[i] == ' ') break;
- fromname.reset();
- fromname.append(p+5, i-5);
+ for (i=0; i<l; i++)
+ {
+ if (!p[i])
+ break;
+ if (p[i] == '>')
+ break;
+ if (isspace(p[i]))
+ break;
}
- else break;
+ fromname.reset();
+ fromname.append(p, i);
+ break;
}
- msgoffset=msgstart;
}
diff --git a/maildrop/messageinfo.h b/maildrop/messageinfo.h
index e8417d3..450ca49 100644
--- a/maildrop/messageinfo.h
+++ b/maildrop/messageinfo.h
@@ -11,21 +11,18 @@ class Message;
///////////////////////////////////////////////////////////////////////////
//
// The MessageInfo class collects information about a message - namely
-// it calculates where the message headers actually start in the Message
-// class. We ignore blank lines and "From " lines at the beginning of
-// the message
+// it extract the email address from the Return-Path: header, if present.
//
///////////////////////////////////////////////////////////////////////////
class MessageInfo {
public:
- off_t msgoffset; // Skip leading blank lines and From header
Buffer fromname; // Envelope sender
- MessageInfo() : msgoffset(0) {}
+ MessageInfo() {}
~MessageInfo() {}
void info(Message &);
- void filtered() { msgoffset=0; }
+ void filtered() {}
} ;
#endif
diff --git a/maildrop/mio.C b/maildrop/mio.C
index 07ea08d..c6311df 100644
--- a/maildrop/mio.C
+++ b/maildrop/mio.C
@@ -8,7 +8,7 @@
#include "mio.h"
#include "funcs.h"
#include "buffer.h"
-
+#include "rfc2045/rfc2045.h"
int mopen(const char *fname, int flags, mode_t mode)
{
@@ -57,7 +57,7 @@ int n;
//-------------------------------------------------------------------------
-Mio::Mio() : fd_(-1), readcnt(0), writecnt(0), err(0)
+Mio::Mio() : fd_(-1), readcnt(0), writecnt(0), err(0), rfc2045p(0)
{
}
@@ -94,6 +94,9 @@ int Mio::fill()
err= -1;
return (-1);
}
+ if (rfc2045p)
+ rfc2045_parse(rfc2045p, (const char *)buf, readcnt);
+
--readcnt;
return (*(readptr=buf)++);
}
diff --git a/maildrop/mio.h b/maildrop/mio.h
index e53053f..6f5e250 100644
--- a/maildrop/mio.h
+++ b/maildrop/mio.h
@@ -30,8 +30,11 @@ class Mio {
int readcnt;
int writecnt;
int err;
- unsigned char buf[1024];
+
+ unsigned char buf[8192];
public:
+ struct rfc2045 *rfc2045p;
+
Mio();
virtual ~Mio();
int Open(const char *, int, mode_t=0666);