--- a/src/internfile/mh_mail.cpp
+++ b/src/internfile/mh_mail.cpp
@@ -1,5 +1,5 @@
#ifndef lint
-static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.14 2006-04-07 08:51:15 dockes Exp $ (C) 2005 J.F.Dockes";
+static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.15 2006-09-05 08:05:02 dockes Exp $ (C) 2005 J.F.Dockes";
#endif
/*
* This program is free software; you can redistribute it and/or modify
@@ -47,9 +47,6 @@
using namespace std;
#endif /* NO_NAMESPACES */
-static void
-walkmime(RclConfig *cnf, string &out, Binc::MimePart& doc, int depth);
-
MimeHandlerMail::~MimeHandlerMail()
{
if (m_vfp) {
@@ -241,18 +238,17 @@
docout.text += string("Subject: ") + transcoded + string("\n");
}
- LOGDEB2(("MimeHandlerMail::processone: ismultipart %d mime subtype '%s'\n",
+ LOGDEB2(("MimeHandlerMail::processone:ismultipart %d mime subtype '%s'\n",
doc.isMultipart(), doc.getSubType().c_str()));
- walkmime(m_conf, docout.text, doc, 0);
-
- // LOGDEB(("MimeHandlerMail::processone: text: '%s'\n", docout.text.c_str()));
+ walkmime(docout.text, doc, 0);
+
+ LOGDEB2(("MimeHandlerMail::processone:text:[%s]\n", docout.text.c_str()));
return MimeHandler::MHDone;
}
// Recursively walk the message mime parts and concatenate all the
// inline html or text that we find anywhere.
-static void walkmime(RclConfig *cnf, string &out, Binc::MimePart& doc,
- int depth)
+void MimeHandlerMail::walkmime(string &out, Binc::MimePart& doc, int depth)
{
if (depth > 5) {
LOGINFO(("walkmime: max depth exceeded\n"));
@@ -269,7 +265,7 @@
if (!stringicmp("mixed", doc.getSubType()) ||
!stringicmp("related", doc.getSubType())) {
for (it = doc.members.begin(); it != doc.members.end();it++) {
- walkmime(cnf, out, *it, depth+1);
+ walkmime(out, *it, depth+1);
}
} else if (!stringicmp("alternative", doc.getSubType())) {
std::vector<Binc::MimePart>::iterator ittxt, ithtml;
@@ -292,15 +288,14 @@
}
if (ittxt != doc.members.end()) {
LOGDEB2(("walkmime: alternative: chose text/plain part\n"))
- walkmime(cnf, out, *ittxt, depth+1);
+ walkmime(out, *ittxt, depth+1);
} else if (ithtml != doc.members.end()) {
LOGDEB2(("walkmime: alternative: chose text/html part\n"))
- walkmime(cnf, out, *ithtml, depth+1);
+ walkmime(out, *ithtml, depth+1);
}
}
} else {
- // If content-type is text or html and content-disposition is inline,
- // decode and add to text.
+ // "Simple" part. See what it is:
// Get and parse content-type header.
Binc::HeaderItem hi;
@@ -311,6 +306,43 @@
LOGDEB2(("walkmime:content-type: %s\n", ctt.c_str()));
MimeHeaderValue content_type;
parseMimeHeaderValue(ctt, content_type);
+
+ // Get and parse Content-Disposition header
+ string ctd = "inline";
+ if (doc.h.getFirstHeader("Content-Disposition", hi)) {
+ ctd = hi.getValue();
+ }
+ MimeHeaderValue content_disposition;
+ parseMimeHeaderValue(ctd, content_disposition);
+
+ LOGDEB2(("Content_disposition:[%s]\n",
+ content_disposition.value.c_str()));
+
+ // If this is an attachment, we index the file name if any and, when
+ // previewing, at least show that it was there.
+ if (!stringlowercmp("attachment", content_disposition.value)) {
+ string rafn = "NoFileName", afn;
+ map<string,string>::const_iterator it;
+ it = content_disposition.params.find(string("filename"));
+ if (it != content_type.params.end())
+ rafn = it->second;
+ rfc2047_decode(rafn, afn);
+ out += "\n";
+ if (m_forPreview)
+ out += "[Attachment: ";
+ out += afn;
+ if (m_forPreview)
+ out += "]";
+ out += "\n\n";
+ // Attachment: we're done with this part
+ return;
+ }
+
+ // The only other disposition that interests us is "inline", and then
+ // this has to be plain text or html
+ if (stringlowercmp("inline", content_disposition.value)) {
+ return;
+ }
if (stringlowercmp("text/plain", content_type.value) &&
stringlowercmp("text/html", content_type.value)) {
return;
@@ -334,17 +366,6 @@
!stringlowercmp("unknown", charset) ) {
charset = "iso-8859-1";
}
-
- // Content disposition
- string ctd = "inline";
- if (doc.h.getFirstHeader("Content-Disposition", hi)) {
- ctd = hi.getValue();
- }
- MimeHeaderValue content_disposition;
- parseMimeHeaderValue(ctd, content_disposition);
- if (stringlowercmp("inline", content_disposition.value)) {
- return;
- }
// Content transfer encoding
string cte = "7bit";
@@ -357,7 +378,7 @@
string body;
doc.getBody(body, 0, doc.bodylength);
- // Decode content transfer encoding
+ // Decode according to content transfer encoding
if (!stringlowercmp("quoted-printable", cte)) {
string decoded;
if (!qp_decode(body, decoded)) {
@@ -381,23 +402,24 @@
body = decoded;
}
- string transcoded;
+ // Handle html stripping and transcoding to utf8
+ string utf8;
if (!stringlowercmp("text/html", content_type.value)) {
MimeHandlerHtml mh;
Rcl::Doc hdoc;
mh.charsethint = charset;
- mh.mkDoc(cnf, "", body, content_type.value, hdoc);
- transcoded = hdoc.text;
+ mh.mkDoc(m_conf, "", body, content_type.value, hdoc);
+ utf8 = hdoc.text;
} else {
// Transcode to utf-8
- if (!transcode(body, transcoded, charset, "UTF-8")) {
+ if (!transcode(body, utf8, charset, "UTF-8")) {
LOGERR(("walkmime: transcode failed from cs '%s' to UTF-8\n",
charset.c_str()));
- transcoded = body;
- }
- }
-
- out += string("\r\n") + transcoded;
+ utf8 = body;
+ }
+ }
+
+ out += string("\r\n") + utf8;
LOGDEB2(("walkmime: out now: [%s]\n", out.c_str()));
}
}