|
a/src/internfile/mh_mail.cpp |
|
b/src/internfile/mh_mail.cpp |
|
... |
|
... |
277 |
|
277 |
|
278 |
// Special case for text/plain content. Internfile should deal
|
278 |
// Special case for text/plain content. Internfile should deal
|
279 |
// with this but it expects text/plain to be utf-8 already, so we
|
279 |
// with this but it expects text/plain to be utf-8 already, so we
|
280 |
// handle the transcoding if needed
|
280 |
// handle the transcoding if needed
|
281 |
if (m_metaData[cstr_dj_keymt] == cstr_textplain) {
|
281 |
if (m_metaData[cstr_dj_keymt] == cstr_textplain) {
|
282 |
string utf8;
|
282 |
if (!txtdcode("MimeHandlerMail::processAttach"))
|
283 |
if (!transcode(body, utf8, m_metaData[cstr_dj_keycharset], cstr_utf8)) {
|
|
|
284 |
LOGERR((" processAttach: transcode to utf-8 failed for charset "
|
|
|
285 |
"[%s]\n", m_metaData[cstr_dj_keycharset].c_str()));
|
|
|
286 |
// can't transcode at all -> data is garbage just erase it
|
|
|
287 |
body.clear();
|
283 |
body.clear();
|
288 |
} else {
|
|
|
289 |
m_metaData[cstr_dj_keycharset] = cstr_utf8;
|
|
|
290 |
body.swap(utf8);
|
|
|
291 |
}
|
|
|
292 |
}
|
284 |
}
|
293 |
|
285 |
|
294 |
// Ipath
|
286 |
// Ipath
|
295 |
char nbuf[20];
|
287 |
char nbuf[20];
|
296 |
sprintf(nbuf, "%d", m_idx);
|
288 |
sprintf(nbuf, "%d", m_idx);
|
|
... |
|
... |
318 |
}
|
310 |
}
|
319 |
|
311 |
|
320 |
// Handle some headers.
|
312 |
// Handle some headers.
|
321 |
string& text = m_metaData[cstr_dj_keycontent];
|
313 |
string& text = m_metaData[cstr_dj_keycontent];
|
322 |
Binc::HeaderItem hi;
|
314 |
Binc::HeaderItem hi;
|
323 |
string transcoded;
|
315 |
string decoded;
|
324 |
if (doc->h.getFirstHeader("From", hi)) {
|
316 |
if (doc->h.getFirstHeader("From", hi)) {
|
325 |
rfc2047_decode(hi.getValue(), transcoded);
|
317 |
rfc2047_decode(hi.getValue(), decoded);
|
326 |
if (preview())
|
318 |
if (preview())
|
327 |
text += string("From: ");
|
319 |
text += string("From: ");
|
328 |
text += transcoded + cstr_newline;
|
320 |
text += decoded + cstr_newline;
|
329 |
if (depth == 1) {
|
321 |
if (depth == 1) {
|
330 |
m_metaData[cstr_dj_keyauthor] = transcoded;
|
322 |
m_metaData[cstr_dj_keyauthor] = decoded;
|
331 |
}
|
323 |
}
|
332 |
}
|
324 |
}
|
333 |
if (doc->h.getFirstHeader("To", hi)) {
|
325 |
if (doc->h.getFirstHeader("To", hi)) {
|
334 |
rfc2047_decode(hi.getValue(), transcoded);
|
326 |
rfc2047_decode(hi.getValue(), decoded);
|
335 |
if (preview())
|
327 |
if (preview())
|
336 |
text += string("To: ");
|
328 |
text += string("To: ");
|
337 |
text += transcoded + cstr_newline;
|
329 |
text += decoded + cstr_newline;
|
338 |
if (depth == 1) {
|
330 |
if (depth == 1) {
|
339 |
m_metaData[cstr_dj_keyrecipient] = transcoded;
|
331 |
m_metaData[cstr_dj_keyrecipient] = decoded;
|
340 |
}
|
332 |
}
|
341 |
}
|
333 |
}
|
342 |
if (doc->h.getFirstHeader("Cc", hi)) {
|
334 |
if (doc->h.getFirstHeader("Cc", hi)) {
|
343 |
rfc2047_decode(hi.getValue(), transcoded);
|
335 |
rfc2047_decode(hi.getValue(), decoded);
|
344 |
if (preview())
|
336 |
if (preview())
|
345 |
text += string("Cc: ");
|
337 |
text += string("Cc: ");
|
346 |
text += transcoded + cstr_newline;
|
338 |
text += decoded + cstr_newline;
|
347 |
if (depth == 1) {
|
339 |
if (depth == 1) {
|
348 |
m_metaData[cstr_dj_keyrecipient] += " " + transcoded;
|
340 |
m_metaData[cstr_dj_keyrecipient] += " " + decoded;
|
349 |
}
|
341 |
}
|
350 |
}
|
342 |
}
|
351 |
if (doc->h.getFirstHeader("Message-Id", hi)) {
|
343 |
if (doc->h.getFirstHeader("Message-Id", hi)) {
|
352 |
if (depth == 1) {
|
344 |
if (depth == 1) {
|
353 |
m_metaData[cstr_dj_keymsgid] = hi.getValue();
|
345 |
m_metaData[cstr_dj_keymsgid] = hi.getValue();
|
354 |
trimstring(m_metaData[cstr_dj_keymsgid], "<>");
|
346 |
trimstring(m_metaData[cstr_dj_keymsgid], "<>");
|
355 |
}
|
347 |
}
|
356 |
}
|
348 |
}
|
357 |
if (doc->h.getFirstHeader("Date", hi)) {
|
349 |
if (doc->h.getFirstHeader("Date", hi)) {
|
358 |
rfc2047_decode(hi.getValue(), transcoded);
|
350 |
rfc2047_decode(hi.getValue(), decoded);
|
359 |
if (depth == 1) {
|
351 |
if (depth == 1) {
|
360 |
time_t t = rfc2822DateToUxTime(transcoded);
|
352 |
time_t t = rfc2822DateToUxTime(decoded);
|
361 |
if (t != (time_t)-1) {
|
353 |
if (t != (time_t)-1) {
|
362 |
char ascuxtime[100];
|
354 |
char ascuxtime[100];
|
363 |
sprintf(ascuxtime, "%ld", (long)t);
|
355 |
sprintf(ascuxtime, "%ld", (long)t);
|
364 |
m_metaData[cstr_dj_keymd] = ascuxtime;
|
356 |
m_metaData[cstr_dj_keymd] = ascuxtime;
|
365 |
} else {
|
357 |
} else {
|
366 |
// Leave mtime field alone, ftime will be used instead.
|
358 |
// Leave mtime field alone, ftime will be used instead.
|
367 |
LOGDEB(("rfc2822Date...: failed: [%s]\n", transcoded.c_str()));
|
359 |
LOGDEB(("rfc2822Date...: failed: [%s]\n", decoded.c_str()));
|
368 |
}
|
360 |
}
|
369 |
}
|
361 |
}
|
370 |
if (preview())
|
362 |
if (preview())
|
371 |
text += string("Date: ");
|
363 |
text += string("Date: ");
|
372 |
text += transcoded + cstr_newline;
|
364 |
text += decoded + cstr_newline;
|
373 |
}
|
365 |
}
|
374 |
if (doc->h.getFirstHeader("Subject", hi)) {
|
366 |
if (doc->h.getFirstHeader("Subject", hi)) {
|
375 |
rfc2047_decode(hi.getValue(), transcoded);
|
367 |
rfc2047_decode(hi.getValue(), decoded);
|
376 |
if (depth == 1) {
|
368 |
if (depth == 1) {
|
377 |
m_metaData[cstr_dj_keytitle] = transcoded;
|
369 |
m_metaData[cstr_dj_keytitle] = decoded;
|
378 |
m_subject = transcoded;
|
370 |
m_subject = decoded;
|
379 |
}
|
371 |
}
|
380 |
if (preview())
|
372 |
if (preview())
|
381 |
text += string("Subject: ");
|
373 |
text += string("Subject: ");
|
382 |
text += transcoded + cstr_newline;
|
374 |
text += decoded + cstr_newline;
|
383 |
}
|
375 |
}
|
384 |
|
376 |
|
385 |
// Check for the presence of configured additional headers and possibly
|
377 |
// Check for the presence of configured additional headers and possibly
|
386 |
// add them to the metadata (with appropriate field name).
|
378 |
// add them to the metadata (with appropriate field name).
|
387 |
if (!m_addProcdHdrs.empty()) {
|
379 |
if (!m_addProcdHdrs.empty()) {
|
|
... |
|
... |
595 |
m_attachments.push_back(att);
|
587 |
m_attachments.push_back(att);
|
596 |
return;
|
588 |
return;
|
597 |
}
|
589 |
}
|
598 |
|
590 |
|
599 |
// We are dealing with an inline part of text/plain or text/html
|
591 |
// We are dealing with an inline part of text/plain or text/html
|
600 |
// type There may be several such parts, which is why we don't
|
|
|
601 |
// just return a text or html subdoc and let the filter stack
|
592 |
// type. We can't just return a text or html subdoc and let the
|
602 |
// work: we want to concatenate them in place instead
|
593 |
// filter stack work: this would create another subdocument, but
|
|
|
594 |
// we want instead to decode a body part of this message document.
|
603 |
|
595 |
|
604 |
LOGDEB2(("walkmime: final: body start offset %d, length %d\n",
|
596 |
LOGDEB2(("walkmime: final: body start offset %d, length %d\n",
|
605 |
doc->getBodyStartOffset(), doc->getBodyLength()));
|
597 |
doc->getBodyStartOffset(), doc->getBodyLength()));
|
606 |
string body;
|
598 |
string body;
|
607 |
doc->getBody(body, 0, doc->bodylength);
|
599 |
doc->getBody(body, 0, doc->bodylength);
|
608 |
|
600 |
{
|
609 |
string decoded;
|
601 |
string decoded;
|
610 |
const string *bdp;
|
602 |
const string *bdp;
|
611 |
if (!decodeBody(cte, body, decoded, &bdp)) {
|
603 |
if (!decodeBody(cte, body, decoded, &bdp)) {
|
612 |
LOGERR(("MimeHandlerMail::walkmime: failed decoding body\n"));
|
604 |
LOGERR(("MimeHandlerMail::walkmime: failed decoding body\n"));
|
613 |
}
|
605 |
}
|
614 |
if (bdp != &body)
|
606 |
if (bdp != &body)
|
615 |
body = decoded;
|
607 |
body.swap(decoded);
|
|
|
608 |
}
|
616 |
|
609 |
|
617 |
// Handle html stripping and transcoding to utf8
|
610 |
// Handle html stripping and transcoding to utf8
|
618 |
if (!stringlowercmp("text/html", content_type.value)) {
|
611 |
if (!stringlowercmp("text/html", content_type.value)) {
|
619 |
MimeHandlerHtml mh(m_config, "text/html");
|
612 |
MimeHandlerHtml mh(m_config, "text/html");
|
620 |
mh.set_property(Dijon::Filter::OPERATING_MODE,
|
613 |
mh.set_property(Dijon::Filter::OPERATING_MODE,
|