diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /maildrop/formatmbox.C | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'maildrop/formatmbox.C')
| -rw-r--r-- | maildrop/formatmbox.C | 173 | 
1 files changed, 173 insertions, 0 deletions
| diff --git a/maildrop/formatmbox.C b/maildrop/formatmbox.C new file mode 100644 index 0000000..3b18927 --- /dev/null +++ b/maildrop/formatmbox.C @@ -0,0 +1,173 @@ +#include	"formatmbox.h" +#include	"message.h" +#include	"messageinfo.h" +#include	"mio.h" +#include	"maildrop.h" +#include	"xconfig.h" +#include	"config.h" +#if HAVE_SYS_STAT_H +#include	<sys/stat.h> +#endif +#include	"mytime.h" +#include	<ctype.h> + + +int	FormatMbox::HasMsg() +{ +	maildrop.msgptr->Rewind(); +	msglinebuf.reset(); +	if (maildrop.msgptr->appendline(msglinebuf,0) < 0)	return (-1); +					// Empty message, do not deliver. + +	return (0); +} + +void	FormatMbox::Init(int flag) +{ +	hdrfrom=""; +	hdrsubject=""; +	msgsize=0; +	inheader=1; + +	do_escape=flag; +	next_func= &FormatMbox::GetLineBuffer; +	if (do_escape) +		next_func= &FormatMbox::GetFromLine; +} + +Buffer	*FormatMbox::GetFromLine(void) +{ +time_t	tm; + +	time(&tm); + +	tempbuf="From "; +	tempbuf += maildrop.msginfo.fromname; +	tempbuf += ' '; + +const char *p=ctime(&tm); +	while (*p && *p != '\n') +	{ +		tempbuf.push(*p); +		++p; +	} +#if	CRLF_TERM +	tempbuf.push('\r'); +#endif +	tempbuf.push('\n'); +	next_func= &FormatMbox::GetLineBuffer; +	return (&tempbuf); +} + +Buffer	*FormatMbox::GetLineBuffer(void) +{ +	if (!(const char *)msglinebuf)	return (0); + +	if (do_escape) +	{ +	const char *p=msglinebuf; +	int	l=msglinebuf.Length(); + +		while (l && *p == '>')	p++, l--; +		if (l >= 5 && +			*p == 'F' && p[1] == 'r' && p[2] == 'o' +				&& p[3] == 'm' && p[4] == ' ') +		{ +			tempbuf=">"; +			tempbuf += msglinebuf; +			msglinebuf=tempbuf; +		} +	} +	if (inheader && *(const char *)msglinebuf == '\n') +		inheader=0; +	if (inheader) +	{ +	const char *p=msglinebuf; +	Buffer	*bufp=0; + +		if ( tolower(*p) == 'f' && tolower(p[1]) == 'r' && +			tolower(p[2]) == 'o' && tolower(p[3]) == 'm' && +			p[4] == ':') +		{ +			p += 5; +			bufp= &hdrfrom; +		} +		else if ( tolower(*p) == 's' && tolower(p[1]) == 'u' && +			tolower(p[2]) == 'b' && tolower(p[3]) == 'j' && +			tolower(p[4]) == 'e' && tolower(p[5]) == 'c' && +			tolower(p[6]) == 't' && p[7] == ':') +		{ +			p += 8; +			bufp= &hdrsubject; +		} +		if (bufp) +		{ +		int	l; + +			while (*p != '\n' && isspace(*p))	p++; +			for (l=0; p[l] != '\n'; l++) +				; +			bufp->append(p, l); +		} +	} + +#if	CRLF_TERM +	msglinebuf.pop();	// Drop terminating \n +	msglinebuf.push('\r'); +	msglinebuf.push('\n'); +#endif +	next_func= &FormatMbox::GetNextLineBuffer; +	msgsize += msglinebuf.Length(); +	return (&msglinebuf); +} + +Buffer	*FormatMbox::GetNextLineBuffer(void) +{ +	msglinebuf.reset(); +	if (maildrop.msgptr->appendline(msglinebuf,0) == 0) +		return (GetLineBuffer()); +	return (0);	// END OF FILE +} + +int	FormatMbox::DeliverTo(class Mio &mio) +{ +Buffer	*bufptr; + +	while ((bufptr=NextLine()) != NULL) +	{ +		if (mio.write((const char *)*bufptr, bufptr->Length()) < 0) +		{ +write_error: +			merr << "maildrop: error writing to mailbox.\n"; +			mio.Close(); +			return (-1); +		} +	} + +	if (do_escape && mio.write( +#if	CRLF_TERM +			"\r\n", 2 +#else +			"\n", 1 +#endif +			) < 0) +			goto write_error; + +	if (mio.flush() < 0) +		goto write_error; + +	if (fsync(mio.fd()) < 0) +	{ +	struct	stat	stat_buf; + +		// fsync() failure on a regular file means trouble. + +		if (fstat(mio.fd(), &stat_buf) == 0 && +			S_ISREG(stat_buf.st_mode)) +			goto write_error; +	} + +	mio.Close(); +	if (mio.errflag())	return (-1); +	return (0); +} | 
