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