Commit b55f4b3b authored by Jean-Francois Dockes's avatar Jean-Francois Dockes
Browse files

add nomd5types parameter to set file types for which dedup is not that useful...

add nomd5types parameter to set file types for which dedup is not that useful and computation is expensive (e.g. audio files). Replace "call parent" misfeature with call to virtual in MimeHandler constructor. Fix log calls indent
parent fea8ff6e
......@@ -34,14 +34,6 @@
using namespace std;
MimeHandlerExec::MimeHandlerExec(RclConfig *cnf, const std::string& id)
: RecollFilter(cnf, id), missingHelper(false), m_filtermaxseconds(900),
m_filtermaxmbytes(0)
{
m_config->getConfParam("filtermaxseconds", &m_filtermaxseconds);
m_config->getConfParam("filtermaxmbytes", &m_filtermaxmbytes);
}
MEAdv::MEAdv(int maxsecs)
: m_filtermaxseconds(maxsecs)
{
......@@ -55,10 +47,11 @@ void MEAdv::reset()
void MEAdv::newData(int n)
{
LOGDEB2("MHExec:newData(" << (n) << ")\n" );
LOGDEB2("MHExec:newData(" << n << ")\n");
if (m_filtermaxseconds > 0 &&
time(0L) - m_start > m_filtermaxseconds) {
LOGERR("MimeHandlerExec: filter timeout (" << (m_filtermaxseconds) << " S)\n" );
LOGERR("MimeHandlerExec: filter timeout (" << m_filtermaxseconds <<
" S)\n");
throw HandlerTimeout();
}
// If a cancel request was set by the signal handler (or by us
......@@ -67,9 +60,65 @@ void MEAdv::newData(int n)
CancelCheck::instance().checkCancel();
}
MimeHandlerExec::MimeHandlerExec(RclConfig *cnf, const std::string& id)
: RecollFilter(cnf, id), missingHelper(false), m_filtermaxseconds(900),
m_filtermaxmbytes(0), m_handlernomd5(false), m_hnomd5init(false),
m_nomd5(false)
{
m_config->getConfParam("filtermaxseconds", &m_filtermaxseconds);
m_config->getConfParam("filtermaxmbytes", &m_filtermaxmbytes);
}
bool MimeHandlerExec::set_document_file_impl(const std::string& mt,
const std::string &file_path)
{
// Can't do this in constructor as script name not set yet. Do it
// once on first call
unordered_set<string> nomd5tps;
bool tpsread(false);
if (false == m_hnomd5init) {
m_hnomd5init = true;
if (m_config->getConfParam("nomd5types", &nomd5tps)) {
tpsread = true;
if (!nomd5tps.empty()) {
if (params.size() &&
nomd5tps.find(path_getsimple(params[0])) !=
nomd5tps.end()) {
m_handlernomd5 = true;
}
// On windows the 1st param is often a script interp
// name (e.g. "python", and the script name is 2nd
if (params.size() > 1 &&
nomd5tps.find(path_getsimple(params[1])) !=
nomd5tps.end()) {
m_handlernomd5 = true;
}
}
}
}
m_nomd5 = m_handlernomd5;
if (!m_nomd5) {
// Check for MIME type based md5 suppression
if (!tpsread) {
m_config->getConfParam("nomd5types", &nomd5tps);
}
if (nomd5tps.find(mt) != nomd5tps.end()) {
m_nomd5 = true;
}
}
m_fn = file_path;
m_havedoc = true;
return true;
}
bool MimeHandlerExec::skip_to_document(const string& ipath)
{
LOGDEB("MimeHandlerExec:skip_to_document: [" << (ipath) << "]\n" );
LOGDEB("MimeHandlerExec:skip_to_document: [" << ipath << "]\n");
m_ipath = ipath;
return true;
}
......@@ -82,13 +131,13 @@ bool MimeHandlerExec::next_document()
return false;
m_havedoc = false;
if (missingHelper) {
LOGDEB("MimeHandlerExec::next_document(): helper known missing\n" );
LOGDEB("MimeHandlerExec::next_document(): helper known missing\n");
return false;
}
if (params.empty()) {
// Hu ho
LOGERR("MimeHandlerExec::mkDoc: empty params\n" );
LOGERR("MimeHandlerExec::next_document: empty params\n");
m_reason = "RECFILTERROR BADCONFIG";
return false;
}
......@@ -110,7 +159,7 @@ bool MimeHandlerExec::next_document()
mexec.setAdvise(&adv);
mexec.putenv("RECOLL_CONFDIR", m_config->getConfDir());
mexec.putenv(m_forPreview ? "RECOLL_FILTER_FORPREVIEW=yes" :
"RECOLL_FILTER_FORPREVIEW=no");
"RECOLL_FILTER_FORPREVIEW=no");
mexec.setrlimit_as(m_filtermaxmbytes);
int status;
......@@ -125,7 +174,8 @@ bool MimeHandlerExec::next_document()
}
if (status) {
LOGERR("MimeHandlerExec: command status 0x" << (status) << " for " << (cmd) << "\n" );
LOGERR("MimeHandlerExec: command status 0x" << status << " for " <<
cmd << "\n");
if (WIFEXITED(status) && WEXITSTATUS(status) == 127) {
// That's how execmd signals a failed exec (most probably
// a missing command). Let'hope no filter uses the same value as
......@@ -188,12 +238,13 @@ void MimeHandlerExec::finaldetails()
m_metaData[cstr_dj_keymt] = cfgFilterOutputMtype.empty() ? "text/html" :
cfgFilterOutputMtype;
if (!m_forPreview) {
if (!m_forPreview && !m_nomd5) {
string md5, xmd5, reason;
if (MD5File(m_fn, md5, &reason)) {
m_metaData[cstr_dj_keymd5] = MD5HexPrint(md5, xmd5);
} else {
LOGERR("MimeHandlerExec: cant compute md5 for [" << (m_fn) << "]: " << (reason) << "\n" );
LOGERR("MimeHandlerExec: cant compute md5 for [" << m_fn << "]: " <<
reason << "\n");
}
}
......
......@@ -62,14 +62,6 @@ class MimeHandlerExec : public RecollFilter {
MimeHandlerExec(RclConfig *cnf, const std::string& id);
virtual bool set_document_file(const std::string& mt,
const std::string &file_path) {
RecollFilter::set_document_file(mt, file_path);
m_fn = file_path;
m_havedoc = true;
return true;
}
virtual bool next_document();
virtual bool skip_to_document(const std::string& ipath);
......@@ -80,9 +72,17 @@ class MimeHandlerExec : public RecollFilter {
}
protected:
virtual bool set_document_file_impl(const std::string& mt,
const std::string& file_path);
std::string m_fn;
std::string m_ipath;
// md5 computation excluded by handler name: can't change after init
bool m_handlernomd5;
bool m_hnomd5init;
// If md5 not excluded by handler name, allow/forbid depending on mime
bool m_nomd5;
// Set up the character set metadata fields and possibly transcode
// text/plain output.
// @param charset when called from mh_execm, a possible explicit
......
......@@ -178,7 +178,7 @@ bool MimeHandlerExecMultiple::next_document()
ostringstream obuf;
string file_md5;
if (m_filefirst) {
if (!m_forPreview) {
if (!m_forPreview && !m_nomd5) {
string md5, xmd5, reason;
if (MD5File(m_fn, md5, &reason)) {
file_md5 = MD5HexPrint(md5, xmd5);
......
......@@ -102,22 +102,27 @@ class MimeHandlerExecMultiple : public MimeHandlerExec {
/////// End un-cleared stuff.
public:
MimeHandlerExecMultiple(RclConfig *cnf, const string& id)
: MimeHandlerExec(cnf, id)
{}
MimeHandlerExecMultiple(RclConfig *cnf, const std::string& id)
: MimeHandlerExec(cnf, id) {
}
// No resources to clean up, the ExecCmd destructor does it.
virtual ~MimeHandlerExecMultiple() {}
virtual bool set_document_file(const string& mt, const string &file_path) {
m_filefirst = true;
return MimeHandlerExec::set_document_file(mt, file_path);
}
virtual bool next_document();
// skip_to and clear inherited from MimeHandlerExec
protected:
// This is the only 2nd-level derived handler class. Use call-super.
virtual bool set_document_file_impl(const std::string& mt,
const std::string &file_path) {
m_filefirst = true;
return MimeHandlerExec::set_document_file_impl(mt, file_path);
}
private:
bool startCmd();
bool readDataElement(string& name, string& data);
bool readDataElement(std::string& name, std::string& data);
bool m_filefirst;
int m_maxmemberkb;
MEAdv m_adv;
......
......@@ -34,23 +34,21 @@ using namespace std;
#endif /* NO_NAMESPACES */
bool MimeHandlerHtml::set_document_file(const string& mt, const string &fn)
bool MimeHandlerHtml::set_document_file_impl(const string& mt, const string &fn)
{
LOGDEB0("textHtmlToDoc: " << (fn) << "\n" );
RecollFilter::set_document_file(mt, fn);
LOGDEB0("textHtmlToDoc: " << fn << "\n");
string otext;
if (!file_to_string(fn, otext)) {
LOGINFO("textHtmlToDoc: cant read: " << (fn) << "\n" );
LOGINFO("textHtmlToDoc: cant read: " << fn << "\n");
return false;
}
m_filename = fn;
return set_document_string(mt, otext);
}
bool MimeHandlerHtml::set_document_string(const string& mt,
const string& htext)
bool MimeHandlerHtml::set_document_string_impl(const string& mt,
const string& htext)
{
RecollFilter::set_document_string(mt, htext);
m_html = htext;
m_havedoc = true;
......@@ -73,12 +71,14 @@ bool MimeHandlerHtml::next_document()
m_filename.erase();
string charset = m_dfltInputCharset;
LOGDEB("MHHtml::next_doc.: default supposed input charset: [" << (charset) << "]\n" );
LOGDEB("MHHtml::next_doc.: default supposed input charset: [" << charset
<< "]\n");
// Override default input charset if someone took care to set one:
map<string,string>::const_iterator it = m_metaData.find(cstr_dj_keycharset);
if (it != m_metaData.end() && !it->second.empty()) {
charset = it->second;
LOGDEB("MHHtml: next_doc.: input charset from ext. metadata: [" << (charset) << "]\n" );
LOGDEB("MHHtml: next_doc.: input charset from ext. metadata: [" <<
charset << "]\n");
}
// - We first try to convert from the supposed charset
......@@ -91,13 +91,15 @@ bool MimeHandlerHtml::next_document()
MyHtmlParser result;
for (int pass = 0; pass < 2; pass++) {
string transcoded;
LOGDEB("Html::mkDoc: pass " << (pass) << "\n" );
LOGDEB("Html::mkDoc: pass " << pass << "\n");
MyHtmlParser p;
// Try transcoding. If it fails, use original text.
int ecnt;
if (!transcode(m_html, transcoded, charset, "UTF-8", &ecnt)) {
LOGDEB("textHtmlToDoc: transcode failed from cs '" << (charset) << "' to UTF-8 for[" << (fn.empty()?"unknown":fn) << "]" );
LOGDEB("textHtmlToDoc: transcode failed from cs '" <<
charset << "' to UTF-8 for[" << (fn.empty()?"unknown":fn) <<
"]");
transcoded = m_html;
// We don't know the charset, at all
p.reset_charsets();
......@@ -105,9 +107,11 @@ bool MimeHandlerHtml::next_document()
} else {
if (ecnt) {
if (pass == 0) {
LOGDEB("textHtmlToDoc: init transcode had " << (ecnt) << " errors for [" << (fn.empty()?"unknown":fn) << "]\n" );
LOGDEB("textHtmlToDoc: init transcode had " << ecnt <<
" errors for ["<<(fn.empty()?"unknown":fn)<< "]\n");
} else {
LOGERR("textHtmlToDoc: final transcode had " << (ecnt) << " errors for [" << (fn.empty()?"unknown":fn) << "]\n" );
LOGERR("textHtmlToDoc: final transcode had " << ecnt <<
" errors for ["<< (fn.empty()?"unknown":fn)<< "]\n");
}
}
// charset has the putative source charset, transcoded is now
......@@ -145,15 +149,16 @@ bool MimeHandlerHtml::next_document()
break;
}
LOGDEB("textHtmlToDoc: charset [" << (charset) << "] doc charset [" << (result.get_charset()) << "]\n" );
LOGDEB("textHtmlToDoc: charset [" << charset << "] doc charset ["<<
result.get_charset() << "]\n");
if (!result.get_charset().empty() &&
!samecharset(result.get_charset(), result.fromcharset)) {
LOGDEB("textHtmlToDoc: reparse for charsets\n" );
LOGDEB("textHtmlToDoc: reparse for charsets\n");
// Set the origin charset as specified in document before
// transcoding again
charset = result.get_charset();
} else {
LOGERR("textHtmlToDoc:: error: non charset exception\n" );
LOGERR("textHtmlToDoc:: error: non charset exception\n");
return false;
}
}
......
......@@ -26,22 +26,18 @@
*/
class MimeHandlerHtml : public RecollFilter {
public:
MimeHandlerHtml(RclConfig *cnf, const string& id)
: RecollFilter(cnf, id)
{
}
virtual ~MimeHandlerHtml()
{
MimeHandlerHtml(RclConfig *cnf, const std::string& id)
: RecollFilter(cnf, id) {
}
virtual bool set_document_file(const string& mt, const string &file_path);
virtual bool set_document_string(const string& mt, const string &data);
virtual ~MimeHandlerHtml() {}
virtual bool is_data_input_ok(DataInput input) const {
if (input == DOCUMENT_FILE_NAME || input == DOCUMENT_STRING)
return true;
return false;
}
virtual bool next_document();
const string& get_html()
const std::string& get_html()
{
return m_html;
}
......@@ -50,9 +46,15 @@ class MimeHandlerHtml : public RecollFilter {
m_html.erase();
RecollFilter::clear();
}
protected:
virtual bool set_document_file_impl(const std::string& mt,
const std::string &file_path);
virtual bool set_document_string_impl(const std::string& mt,
const std::string &data);
private:
string m_filename;
string m_html;
std::string m_filename;
std::string m_html;
};
#endif /* _HTML_H_INCLUDED_ */
......@@ -87,10 +87,9 @@ void MimeHandlerMail::clear()
RecollFilter::clear();
}
bool MimeHandlerMail::set_document_file(const string& mt, const string &fn)
bool MimeHandlerMail::set_document_file_impl(const string& mt, const string &fn)
{
LOGDEB("MimeHandlerMail::set_document_file(" << (fn) << ")\n" );
RecollFilter::set_document_file(mt, fn);
LOGDEB("MimeHandlerMail::set_document_file(" << fn << ")\n");
if (m_fd >= 0) {
close(m_fd);
m_fd = -1;
......@@ -103,12 +102,13 @@ bool MimeHandlerMail::set_document_file(const string& mt, const string &fn)
if (MD5File(fn, md5, &reason)) {
m_metaData[cstr_dj_keymd5] = MD5HexPrint(md5, xmd5);
} else {
LOGERR("MimeHandlerMail: cant md5 [" << (fn) << "]: " << (reason) << "\n" );
LOGERR("MimeHandlerMail: md5 [" << fn << "]: " << reason << "\n");
}
}
m_fd = open(fn.c_str(), 0);
if (m_fd < 0) {
LOGERR("MimeHandlerMail::set_document_file: open(" << (fn) << ") errno " << (errno) << "\n" );
LOGERR("MimeHandlerMail::set_document_file: open(" << fn <<
") errno " << errno << "\n");
return false;
}
#if defined O_NOATIME && O_NOATIME != 0
......@@ -120,19 +120,18 @@ bool MimeHandlerMail::set_document_file(const string& mt, const string &fn)
m_bincdoc = new Binc::MimeDocument;
m_bincdoc->parseFull(m_fd);
if (!m_bincdoc->isHeaderParsed() && !m_bincdoc->isAllParsed()) {
LOGERR("MimeHandlerMail::mkDoc: mime parse error for " << (fn) << "\n" );
LOGERR("MimeHandlerMail::mkDoc: mime parse error for " << fn << "\n");
return false;
}
m_havedoc = true;
return true;
}
bool MimeHandlerMail::set_document_string(const string& mt,
const string &msgtxt)
bool MimeHandlerMail::set_document_string_impl(const string& mt,
const string& msgtxt)
{
LOGDEB1("MimeHandlerMail::set_document_string\n" );
LOGDEB2("Message text: [" << (msgtxt) << "]\n" );
RecollFilter::set_document_string(mt, msgtxt);
LOGDEB1("MimeHandlerMail::set_document_string\n");
LOGDEB2("Message text: [" << msgtxt << "]\n");
delete m_stream;
if (!m_forPreview) {
......@@ -142,17 +141,19 @@ bool MimeHandlerMail::set_document_string(const string& mt,
}
if ((m_stream = new stringstream(msgtxt)) == 0 || !m_stream->good()) {
LOGERR("MimeHandlerMail::set_document_string: stream create error.msgtxt.size() " << (int(msgtxt.size())) << "\n" );
LOGERR("MimeHandlerMail::set_document_string: stream create error."
"msgtxt.size() " << msgtxt.size() << "\n");
return false;
}
delete m_bincdoc;
if ((m_bincdoc = new Binc::MimeDocument) == 0) {
LOGERR("MimeHandlerMail::set_doc._string: new Binc:Document failed. Out of memory?" );
LOGERR("MimeHandlerMail::set_doc._string: new Binc:Document failed. "
"Out of memory?");
return false;
}
m_bincdoc->parseFull(*m_stream);
if (!m_bincdoc->isHeaderParsed() && !m_bincdoc->isAllParsed()) {
LOGERR("MimeHandlerMail::set_document_string: mime parse error\n" );
LOGERR("MimeHandlerMail::set_document_string: mime parse error\n");
return false;
}
m_havedoc = true;
......@@ -161,14 +162,14 @@ bool MimeHandlerMail::set_document_string(const string& mt,
bool MimeHandlerMail::skip_to_document(const string& ipath)
{
LOGDEB("MimeHandlerMail::skip_to_document(" << (ipath) << ")\n" );
LOGDEB("MimeHandlerMail::skip_to_document(" << ipath << ")\n");
if (m_idx == -1) {
// No decoding done yet. If ipath is null need do nothing
if (ipath.empty() || ipath == "-1")
return true;
// ipath points to attachment: need to decode message
if (!next_document()) {
LOGERR("MimeHandlerMail::skip_to_doc: next_document failed\n" );
LOGERR("MimeHandlerMail::skip_to_doc: next_document failed\n");
return false;
}
}
......@@ -178,7 +179,8 @@ bool MimeHandlerMail::skip_to_document(const string& ipath)
bool MimeHandlerMail::next_document()
{
LOGDEB("MimeHandlerMail::next_document m_idx " << (m_idx) << " m_havedoc " << (m_havedoc) << "\n" );
LOGDEB("MimeHandlerMail::next_document m_idx " << m_idx << " m_havedoc " <<
m_havedoc << "\n");
if (!m_havedoc)
return false;
bool res = false;
......@@ -186,7 +188,9 @@ bool MimeHandlerMail::next_document()
if (m_idx == -1) {
m_metaData[cstr_dj_keymt] = cstr_textplain;
res = processMsg(m_bincdoc, 0);
LOGDEB1("MimeHandlerMail::next_document: mt " << (m_metaData[cstr_dj_keymt]) << ", att cnt " << (m_attachments.size()) << "\n" );
LOGDEB1("MimeHandlerMail::next_document: mt " <<
m_metaData[cstr_dj_keymt] << ", att cnt " <<
m_attachments.size() << "\n");
const string& txt = m_metaData[cstr_dj_keycontent];
if (m_startoftext < txt.size())
m_metaData[cstr_dj_keyabstract] =
......@@ -221,16 +225,16 @@ static bool decodeBody(const string& cte, // Content transfer encoding
if (!stringlowercmp("quoted-printable", cte)) {
if (!qp_decode(body, decoded)) {
LOGERR("decodeBody: quoted-printable decoding failed !\n" );
LOGDEB(" Body: \n" << (body) << "\n" );
LOGERR("decodeBody: quoted-printable decoding failed !\n");
LOGDEB(" Body: \n" << body << "\n");
return false;
}
*respp = &decoded;
} else if (!stringlowercmp("base64", cte)) {
if (!base64_decode(body, decoded)) {
// base64 encoding errors are actually relatively common
LOGERR("decodeBody: base64 decoding failed !\n" );
LOGDEB(" Body: \n" << (body) << "\n" );
LOGERR("decodeBody: base64 decoding failed !\n");
LOGDEB(" Body: \n" << body << "\n");
return false;
}
*respp = &decoded;
......@@ -240,7 +244,7 @@ static bool decodeBody(const string& cte, // Content transfer encoding
bool MimeHandlerMail::processAttach()
{
LOGDEB("MimeHandlerMail::processAttach() m_idx " << (m_idx) << "\n" );
LOGDEB("MimeHandlerMail::processAttach() m_idx " << m_idx << "\n");
if (!m_havedoc)
return false;
if (m_idx >= (int)m_attachments.size()) {
......@@ -254,7 +258,8 @@ bool MimeHandlerMail::processAttach()
m_metaData[cstr_dj_keycharset] = att->m_charset;
m_metaData[cstr_dj_keyfn] = att->m_filename;
m_metaData[cstr_dj_keytitle] = att->m_filename + " (" + m_subject + ")";
LOGDEB1(" processAttach:ct [" << (att->m_contentType) << "] cs [" << (att->m_charset) << "] fn [" << (att->m_filename) << "]\n" );
LOGDEB1(" processAttach:ct [" << att->m_contentType << "] cs [" <<
att->m_charset << "] fn [" << att->m_filename << "]\n");
// Erase current content and replace
m_metaData[cstr_dj_keycontent] = string();
......@@ -305,10 +310,11 @@ bool MimeHandlerMail::processAttach()
// text
bool MimeHandlerMail::processMsg(Binc::MimePart *doc, int depth)
{
LOGDEB2("MimeHandlerMail::processMsg: depth " << (depth) << "\n" );
LOGDEB2("MimeHandlerMail::processMsg: depth " << depth << "\n");
if (depth++ >= maxdepth) {
// Have to stop somewhere
LOGINFO("MimeHandlerMail::processMsg: maxdepth " << (maxdepth) << " exceeded\n" );
LOGINFO("MimeHandlerMail::processMsg: maxdepth " << maxdepth <<
" exceeded\n");
// Return true anyway, better to index partially than not at all
return true;
}
......@@ -360,7 +366,7 @@ bool MimeHandlerMail::processMsg(Binc::MimePart *doc, int depth)
m_metaData[cstr_dj_keymd] = ascuxtime;
} else {
// Leave mtime field alone, ftime will be used instead.
LOGDEB("rfc2822Date...: failed: [" << (decoded) << "]\n" );
LOGDEB("rfc2822Date...: failed: [" << decoded << "]\n");
}
}
if (preview())
......@@ -394,10 +400,12 @@ bool MimeHandlerMail::processMsg(Binc::MimePart *doc, int depth)
text += '\n';
m_startoftext = text.size();
LOGDEB2("MimeHandlerMail::processMsg:ismultipart " << (doc->isMultipart()) << " mime subtype '" << (doc->getSubType()) << "'\n" );
LOGDEB2("MimeHandlerMail::processMsg:ismultipart " <<
doc->isMultipart() << " mime subtype '"<<doc->getSubType()<< "'\n");
walkmime(doc, depth);
LOGDEB2("MimeHandlerMail::processMsg:text:[" << (m_metaData[cstr_dj_keycontent]) << "]\n" );
LOGDEB2("MimeHandlerMail::processMsg:text:[" <<
m_metaData[cstr_dj_keycontent] << "]\n");
return true;
}
......@@ -413,16 +421,17 @@ bool MimeHandlerMail::processMsg(Binc::MimePart *doc, int depth)
// message/rfc822 may also be of interest.
void MimeHandlerMail::walkmime(Binc::MimePart* doc, int depth)
{
LOGDEB2("MimeHandlerMail::walkmime: depth " << (depth) << "\n" );
LOGDEB2("MimeHandlerMail::walkmime: depth " << depth << "\n");
if (depth++ >= maxdepth) {
LOGINFO("walkmime: max depth (" << (maxdepth) << ") exceeded\n" );
LOGINFO("walkmime: max depth (" << maxdepth << ") exceeded\n");
return;
}
string& out = m_metaData[cstr_dj_keycontent];
if (doc->isMultipart()) {
LOGDEB2("walkmime: ismultipart " << (doc->isMultipart()) << " subtype '" << (doc->getSubType()) << "'\n" );
LOGDEB2("walkmime: ismultipart " << doc->isMultipart() <<
" subtype '" << doc->getSubType() << "'\n");
// We only handle alternative, related and mixed (no digests).
std::vector<Binc::MimePart>::iterator it;
......@@ -445,22 +454,22 @@ void MimeHandlerMail::walkmime(Binc::MimePart* doc, int depth)
// Get and parse content-type header
Binc::HeaderItem hi;
if (!it->h.getFirstHeader("Content-Type", hi)) {
LOGDEB("walkmime:no ctent-type header for part " << (i) << "\n" );
LOGDEB("walkmime:no ctent-type header for part "<<i<< "\n");
continue;
}
MimeHeaderValue content_type;
parseMimeHeaderValue(hi.getValue(), content_type);
LOGDEB2("walkmime: C-type: " << (content_type.value) << "\n" );
LOGDEB2("walkmime: C-type: " << content_type.value << "\n");
if (!stringlowercmp(cstr_textplain, content_type.value))
ittxt = it;
else if (!stringlowercmp("text/html", content_type.value))
ithtml = it;
}
if (ittxt != doc->members.end()) {
LOGDEB2("walkmime: alternative: chose text/plain part\n" );
LOGDEB2("walkmime: alternative: chose text/plain part\n");
walkmime(&(*ittxt), depth);
} else if (ithtml != doc->members.end()) {
LOGDEB2("walkmime: alternative: chose text/html part\n" );
LOGDEB2("walkmime: alternative: chose text/html part\n");
walkmime(&(*ithtml), depth);
}
}
......@@ -476,7 +485,7 @@ void MimeHandlerMail::walkmime(Binc::MimePart* doc, int depth)
if (doc->h.getFirstHeader("Content-Type", hi)) {
ctt = hi.getValue();