1 #include	"formatmbox.h"
2 #include	"message.h"
3 #include	"messageinfo.h"
4 #include	"mio.h"
5 #include	"maildrop.h"
6 #include	"xconfig.h"
7 #include	"config.h"
8 #if HAVE_SYS_STAT_H
9 #include	<sys/stat.h>
10 #endif
11 #include	"mytime.h"
12 #include	<ctype.h>
13 
14 static const char rcsid[]="$Id: formatmbox.C,v 1.6 2002/04/08 15:11:02 mrsam Exp $";
15 
HasMsg()16 int	FormatMbox::HasMsg()
17 {
18 	maildrop.msgptr->Rewind();
19 	msglinebuf.reset();
20 	if (maildrop.msgptr->appendline(msglinebuf,0) < 0)	return (-1);
21 					// Empty message, do not deliver.
22 
23 	return (0);
24 }
25 
Init(int flag)26 void	FormatMbox::Init(int flag)
27 {
28 	hdrfrom="";
29 	hdrsubject="";
30 	msgsize=0;
31 	inheader=1;
32 
33 	do_escape=flag;
34 	next_func= &FormatMbox::GetLineBuffer;
35 	if (do_escape)
36 		next_func= &FormatMbox::GetFromLine;
37 }
38 
GetFromLine(void)39 Buffer	*FormatMbox::GetFromLine(void)
40 {
41 time_t	tm;
42 
43 	time(&tm);
44 
45 	tempbuf="From ";
46 	tempbuf += maildrop.msginfo.fromname;
47 	tempbuf += ' ';
48 
49 const char *p=ctime(&tm);
50 	while (*p && *p != '\n')
51 	{
52 		tempbuf.push(*p);
53 		++p;
54 	}
55 #if	CRLF_TERM
56 	tempbuf.push('\r');
57 #endif
58 	tempbuf.push('\n');
59 	next_func= &FormatMbox::GetLineBuffer;
60 	return (&tempbuf);
61 }
62 
GetLineBuffer(void)63 Buffer	*FormatMbox::GetLineBuffer(void)
64 {
65 	if (!(const char *)msglinebuf)	return (0);
66 
67 	if (do_escape)
68 	{
69 	const char *p=msglinebuf;
70 	int	l=msglinebuf.Length();
71 
72 		while (l && *p == '>')	p++, l--;
73 		if (l >= 5 &&
74 			*p == 'F' && p[1] == 'r' && p[2] == 'o'
75 				&& p[3] == 'm' && p[4] == ' ')
76 		{
77 			tempbuf=">";
78 			tempbuf += msglinebuf;
79 			msglinebuf=tempbuf;
80 		}
81 	}
82 	if (inheader && *(const char *)msglinebuf == '\n')
83 		inheader=0;
84 	if (inheader)
85 	{
86 	const char *p=msglinebuf;
87 	Buffer	*bufp=0;
88 
89 		while (*p != '\n' && isspace(*p))	p++;
90 		if ( tolower(*p) == 'f' && tolower(p[1]) == 'r' &&
91 			tolower(p[2]) == 'o' && tolower(p[3]) == 'm' &&
92 			p[4] == ':')
93 		{
94 			p += 5;
95 			bufp= &hdrfrom;
96 		}
97 		else if ( tolower(*p) == 's' && tolower(p[1]) == 'u' &&
98 			tolower(p[2]) == 'b' && tolower(p[3]) == 'j' &&
99 			tolower(p[4]) == 'e' && tolower(p[5]) == 'c' &&
100 			tolower(p[6]) == 't' && p[7] == ':')
101 		{
102 			p += 8;
103 			bufp= &hdrsubject;
104 		}
105 		if (bufp)
106 		{
107 		int	l;
108 
109 			while (*p != '\n' && isspace(*p))	p++;
110 			for (l=0; p[l] != '\n'; l++)
111 				;
112 			bufp->append(p, l);
113 		}
114 	}
115 
116 #if	CRLF_TERM
117 	msglinebuf.pop();	// Drop terminating \n
118 	msglinebuf.push('\r');
119 	msglinebuf.push('\n');
120 #endif
121 	next_func= &FormatMbox::GetNextLineBuffer;
122 	msgsize += msglinebuf.Length();
123 	return (&msglinebuf);
124 }
125 
GetNextLineBuffer(void)126 Buffer	*FormatMbox::GetNextLineBuffer(void)
127 {
128 	msglinebuf.reset();
129 	if (maildrop.msgptr->appendline(msglinebuf,0) == 0)
130 		return (GetLineBuffer());
131 	return (0);	// END OF FILE
132 }
133 
DeliverTo(class Mio & mio)134 int	FormatMbox::DeliverTo(class Mio &mio)
135 {
136 Buffer	*bufptr;
137 
138 	while ((bufptr=NextLine()) != NULL)
139 	{
140 		if (mio.write((const char *)*bufptr, bufptr->Length()) < 0)
141 		{
142 write_error:
143 			merr << "maildrop: error writing to mailbox.\n";
144 			mio.Close();
145 			return (-1);
146 		}
147 	}
148 
149 	if (do_escape && mio.write(
150 #if	CRLF_TERM
151 			"\r\n", 2
152 #else
153 			"\n", 1
154 #endif
155 			) < 0)
156 			goto write_error;
157 
158 	if (mio.flush() < 0)
159 		goto write_error;
160 
161 	if (fsync(mio.fd()) < 0)
162 	{
163 	struct	stat	stat_buf;
164 
165 		// fsync() failure on a regular file means trouble.
166 
167 		if (fstat(mio.fd(), &stat_buf) == 0 &&
168 			S_ISREG(stat_buf.st_mode))
169 			goto write_error;
170 	}
171 
172 	mio.Close();
173 	if (mio.errflag())	return (-1);
174 	return (0);
175 }
176