diff options
| author | Sam Varshavchik | 2013-08-25 20:54:43 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-28 21:07:40 -0400 | 
| commit | 9bb1a8d85390653f702e8ad5556a2cd3793acbfe (patch) | |
| tree | 2aafb33608ec6c69182e00364d324f845a3e7325 | |
| parent | 2ec3d0c52bff3e27242ae214571792c5f2d5299a (diff) | |
| download | courier-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.am | 1 | ||||
| -rw-r--r-- | maildrop/main.C | 10 | ||||
| -rw-r--r-- | maildrop/message.C | 53 | ||||
| -rw-r--r-- | maildrop/message.h | 13 | ||||
| -rw-r--r-- | maildrop/messageinfo.C | 53 | ||||
| -rw-r--r-- | maildrop/messageinfo.h | 9 | ||||
| -rw-r--r-- | maildrop/mio.C | 7 | ||||
| -rw-r--r-- | maildrop/mio.h | 5 | 
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); | 
