|
a/src/internfile/mh_mail.cpp |
|
b/src/internfile/mh_mail.cpp |
1 |
#ifndef lint
|
1 |
#ifndef lint
|
2 |
static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.13 2006-01-23 13:32:28 dockes Exp $ (C) 2005 J.F.Dockes";
|
2 |
static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.14 2006-04-07 08:51:15 dockes Exp $ (C) 2005 J.F.Dockes";
|
3 |
#endif
|
3 |
#endif
|
4 |
/*
|
4 |
/*
|
5 |
* This program is free software; you can redistribute it and/or modify
|
5 |
* This program is free software; you can redistribute it and/or modify
|
6 |
* it under the terms of the GNU General Public License as published by
|
6 |
* it under the terms of the GNU General Public License as published by
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
|
... |
|
... |
50 |
static void
|
50 |
static void
|
51 |
walkmime(RclConfig *cnf, string &out, Binc::MimePart& doc, int depth);
|
51 |
walkmime(RclConfig *cnf, string &out, Binc::MimePart& doc, int depth);
|
52 |
|
52 |
|
53 |
MimeHandlerMail::~MimeHandlerMail()
|
53 |
MimeHandlerMail::~MimeHandlerMail()
|
54 |
{
|
54 |
{
|
55 |
if (vfp) {
|
55 |
if (m_vfp) {
|
56 |
fclose((FILE *)vfp);
|
56 |
fclose((FILE *)m_vfp);
|
57 |
vfp = 0;
|
57 |
m_vfp = 0;
|
58 |
}
|
58 |
}
|
59 |
}
|
59 |
}
|
60 |
|
60 |
|
61 |
// We are called for two different file types: mbox-type folders
|
61 |
// We are called for two different file types: mbox-type folders
|
62 |
// holding multiple messages, and maildir-type files with one message
|
62 |
// holding multiple messages, and maildir-type files with one message
|
|
|
63 |
// ipath is non empty only when we are called for retrieving a single message
|
|
|
64 |
// for preview. It is always empty during indexing, and we fill it up with
|
|
|
65 |
// the message number for the returned doc
|
63 |
MimeHandler::Status
|
66 |
MimeHandler::Status
|
64 |
MimeHandlerMail::mkDoc(RclConfig *cnf, const string &fn,
|
67 |
MimeHandlerMail::mkDoc(RclConfig *cnf, const string &fn,
|
65 |
const string &mtype, Rcl::Doc &docout, string& ipath)
|
68 |
const string &mtype, Rcl::Doc &docout, string& ipath)
|
66 |
{
|
69 |
{
|
67 |
LOGDEB2(("MimeHandlerMail::mkDoc: %s [%s]\n", mtype.c_str(), fn.c_str()));
|
70 |
LOGDEB2(("MimeHandlerMail::mkDoc: %s [%s]\n", mtype.c_str(), fn.c_str()));
|
68 |
conf = cnf;
|
71 |
m_conf = cnf;
|
69 |
|
72 |
|
70 |
if (!stringlowercmp("message/rfc822", mtype)) {
|
73 |
if (!stringlowercmp("message/rfc822", mtype)) {
|
71 |
ipath = "";
|
74 |
ipath = "";
|
72 |
int fd;
|
75 |
int fd;
|
73 |
if ((fd = open(fn.c_str(), 0)) < 0) {
|
76 |
if ((fd = open(fn.c_str(), 0)) < 0) {
|
|
... |
|
... |
95 |
}
|
98 |
}
|
96 |
LOGDEB2(("MimeHandlerMail::processmbox: fn %s, mtarg %d\n", fn.c_str(),
|
99 |
LOGDEB2(("MimeHandlerMail::processmbox: fn %s, mtarg %d\n", fn.c_str(),
|
97 |
mtarg));
|
100 |
mtarg));
|
98 |
|
101 |
|
99 |
FILE *fp;
|
102 |
FILE *fp;
|
|
|
103 |
// Open the file on first call, then save/reuse the file pointer
|
100 |
if (vfp) {
|
104 |
if (!m_vfp) {
|
101 |
fp = (FILE *)vfp;
|
|
|
102 |
} else {
|
|
|
103 |
fp = fopen(fn.c_str(), "r");
|
105 |
fp = fopen(fn.c_str(), "r");
|
104 |
if (fp == 0) {
|
106 |
if (fp == 0) {
|
105 |
LOGERR(("MimeHandlerMail::processmbox: error opening %s\n",
|
107 |
LOGERR(("MimeHandlerMail::processmbox: error opening %s\n",
|
106 |
fn.c_str()));
|
108 |
fn.c_str()));
|
107 |
return MimeHandler::MHError;
|
109 |
return MimeHandler::MHError;
|
108 |
}
|
110 |
}
|
109 |
vfp = fp;
|
111 |
m_vfp = fp;
|
|
|
112 |
} else {
|
|
|
113 |
fp = (FILE *)m_vfp;
|
110 |
}
|
114 |
}
|
|
|
115 |
|
|
|
116 |
// If we are called to retrieve a specific message, seek to bof
|
|
|
117 |
// (then scan up to the message). This is for the case where the
|
|
|
118 |
// same object is reused to fetch several messages (else the fp is
|
|
|
119 |
// just opened no need for a seek). We could also check if the
|
|
|
120 |
// current message number is lower than the requested one and
|
|
|
121 |
// avoid rereading the whole thing in this case. But I'm not sure
|
|
|
122 |
// we're ever used in this way (multiple retrieves on same
|
|
|
123 |
// object). So:
|
111 |
if (mtarg > 0) {
|
124 |
if (mtarg > 0) {
|
112 |
fseek(fp, 0, SEEK_SET);
|
125 |
fseek(fp, 0, SEEK_SET);
|
113 |
msgnum = 0;
|
126 |
m_msgnum = 0;
|
114 |
}
|
127 |
}
|
115 |
|
128 |
|
116 |
off_t start, end;
|
129 |
off_t start, end;
|
117 |
bool iseof = false;
|
130 |
bool iseof = false;
|
118 |
do {
|
131 |
do {
|
|
... |
|
... |
140 |
if (ferror(fp) || feof(fp))
|
153 |
if (ferror(fp) || feof(fp))
|
141 |
iseof = true;
|
154 |
iseof = true;
|
142 |
break;
|
155 |
break;
|
143 |
}
|
156 |
}
|
144 |
}
|
157 |
}
|
145 |
msgnum++;
|
158 |
m_msgnum++;
|
146 |
fseek(fp, end, SEEK_SET);
|
159 |
fseek(fp, end, SEEK_SET);
|
147 |
} while (mtarg > 0 && msgnum < mtarg);
|
160 |
} while (mtarg > 0 && m_msgnum < mtarg);
|
148 |
|
161 |
|
149 |
|
162 |
|
150 |
size_t size = end - start;
|
163 |
size_t size = end - start;
|
151 |
fseek(fp, start, SEEK_SET);
|
164 |
fseek(fp, start, SEEK_SET);
|
152 |
char *cp = (char *)malloc(size);
|
165 |
char *cp = (char *)malloc(size);
|
|
... |
|
... |
167 |
doc.parseFull(s);
|
180 |
doc.parseFull(s);
|
168 |
MimeHandler::Status ret = processone(fn, doc, docout);
|
181 |
MimeHandler::Status ret = processone(fn, doc, docout);
|
169 |
if (ret == MimeHandler::MHError)
|
182 |
if (ret == MimeHandler::MHError)
|
170 |
return ret;
|
183 |
return ret;
|
171 |
char buf[20];
|
184 |
char buf[20];
|
172 |
sprintf(buf, "%d", msgnum);
|
185 |
sprintf(buf, "%d", m_msgnum);
|
173 |
ipath = buf;
|
186 |
ipath = buf;
|
174 |
return iseof ? MimeHandler::MHDone :
|
187 |
return iseof ? MimeHandler::MHDone :
|
175 |
(mtarg > 0) ? MimeHandler::MHDone : MimeHandler::MHAgain;
|
188 |
(mtarg > 0) ? MimeHandler::MHDone : MimeHandler::MHAgain;
|
176 |
}
|
189 |
}
|
177 |
|
190 |
|
|
... |
|
... |
228 |
docout.text += string("Subject: ") + transcoded + string("\n");
|
241 |
docout.text += string("Subject: ") + transcoded + string("\n");
|
229 |
}
|
242 |
}
|
230 |
|
243 |
|
231 |
LOGDEB2(("MimeHandlerMail::processone: ismultipart %d mime subtype '%s'\n",
|
244 |
LOGDEB2(("MimeHandlerMail::processone: ismultipart %d mime subtype '%s'\n",
|
232 |
doc.isMultipart(), doc.getSubType().c_str()));
|
245 |
doc.isMultipart(), doc.getSubType().c_str()));
|
233 |
walkmime(conf, docout.text, doc, 0);
|
246 |
walkmime(m_conf, docout.text, doc, 0);
|
234 |
|
247 |
|
235 |
// LOGDEB(("MimeHandlerMail::processone: text: '%s'\n", docout.text.c_str()));
|
248 |
// LOGDEB(("MimeHandlerMail::processone: text: '%s'\n", docout.text.c_str()));
|
236 |
return MimeHandler::MHDone;
|
249 |
return MimeHandler::MHDone;
|
237 |
}
|
250 |
}
|
238 |
|
251 |
|