Switch to unified view

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.18 2006-09-19 14:30:39 dockes Exp $ (C) 2005 J.F.Dockes";
2
static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.19 2006-09-22 07:19:13 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
...
...
45
45
46
#ifndef NO_NAMESPACES
46
#ifndef NO_NAMESPACES
47
using namespace std;
47
using namespace std;
48
#endif /* NO_NAMESPACES */
48
#endif /* NO_NAMESPACES */
49
49
50
static const int maxdepth = 20;
51
50
MimeHandlerMail::~MimeHandlerMail()
52
MimeHandlerMail::~MimeHandlerMail()
51
{
53
{
52
    if (m_vfp) {
54
    if (m_vfp) {
53
    fclose((FILE *)m_vfp);
55
    fclose((FILE *)m_vfp);
54
    m_vfp = 0;
56
    m_vfp = 0;
...
...
183
    if (!doc.isHeaderParsed() && !doc.isAllParsed()) {
185
    if (!doc.isHeaderParsed() && !doc.isAllParsed()) {
184
    LOGERR(("MimeHandlerMail::processMbox: mime parse error for %s\n",
186
    LOGERR(("MimeHandlerMail::processMbox: mime parse error for %s\n",
185
        fn.c_str()));
187
        fn.c_str()));
186
    return MimeHandler::MHError;
188
    return MimeHandler::MHError;
187
    }
189
    }
190
    LOGDEB2(("Calling processMsg with msgnum %d\n", m_msgnum));
188
    MimeHandler::Status ret = processMsg(docout, doc, 0);
191
    MimeHandler::Status ret = processMsg(docout, doc, 0);
189
    if (ret == MimeHandler::MHError)
192
    if (ret == MimeHandler::MHError)
190
    return ret;
193
    return ret;
191
    char buf[20];
194
    char buf[20];
192
    sprintf(buf, "%d", m_msgnum);
195
    sprintf(buf, "%d", m_msgnum);
...
...
205
// text
208
// text
206
MimeHandler::Status 
209
MimeHandler::Status 
207
MimeHandlerMail::processMsg(Rcl::Doc &docout, Binc::MimePart& doc, 
210
MimeHandlerMail::processMsg(Rcl::Doc &docout, Binc::MimePart& doc, 
208
                int depth)
211
                int depth)
209
{
212
{
213
    LOGDEB2(("MimeHandlerMail::processMsg: depth %d\n", depth));
210
    if (depth >= 5) {
214
    if (depth++ >= maxdepth) {
211
    // Have to stop somewhere
215
    // Have to stop somewhere
212
    LOGDEB(("MimeHandlerMail::processMsg: stopping at depth 5\n"));
216
    LOGDEB(("MimeHandlerMail::processMsg: maxdepth %d exceeded\n", 
217
      maxdepth));
213
    return MimeHandler::MHDone;
218
    return MimeHandler::MHDone;
214
    }
219
    }
215
    
220
    
216
    // Handle some headers. 
221
    // Handle some headers. 
217
    Binc::HeaderItem hi;
222
    Binc::HeaderItem hi;
...
...
224
    rfc2047_decode(hi.getValue(), transcoded);
229
    rfc2047_decode(hi.getValue(), transcoded);
225
    docout.text += string("To: ") + transcoded + string("\n");
230
    docout.text += string("To: ") + transcoded + string("\n");
226
    }
231
    }
227
    if (doc.h.getFirstHeader("Date", hi)) {
232
    if (doc.h.getFirstHeader("Date", hi)) {
228
    rfc2047_decode(hi.getValue(), transcoded);
233
    rfc2047_decode(hi.getValue(), transcoded);
229
    if (depth == 0) {
234
    if (depth == 1) {
230
        time_t t = rfc2822DateToUxTime(transcoded);
235
        time_t t = rfc2822DateToUxTime(transcoded);
231
        if (t != (time_t)-1) {
236
        if (t != (time_t)-1) {
232
        char ascuxtime[100];
237
        char ascuxtime[100];
233
        sprintf(ascuxtime, "%ld", (long)t);
238
        sprintf(ascuxtime, "%ld", (long)t);
234
        docout.dmtime = ascuxtime;
239
        docout.dmtime = ascuxtime;
...
...
239
    }
244
    }
240
    docout.text += string("Date: ") + transcoded + string("\n");
245
    docout.text += string("Date: ") + transcoded + string("\n");
241
    }
246
    }
242
    if (doc.h.getFirstHeader("Subject", hi)) {
247
    if (doc.h.getFirstHeader("Subject", hi)) {
243
    rfc2047_decode(hi.getValue(), transcoded);
248
    rfc2047_decode(hi.getValue(), transcoded);
244
    if (depth == 0)
249
    if (depth == 1)
245
        docout.title = transcoded;
250
        docout.title = transcoded;
246
    docout.text += string("Subject: ") + transcoded + string("\n");
251
    docout.text += string("Subject: ") + transcoded + string("\n");
247
    }
252
    }
248
253
249
    LOGDEB2(("MimeHandlerMail::processMsg:ismultipart %d mime subtype '%s'\n",
254
    LOGDEB2(("MimeHandlerMail::processMsg:ismultipart %d mime subtype '%s'\n",
...
...
263
//      Composite: multipart, message.
268
//      Composite: multipart, message.
264
// 
269
// 
265
// multipart can be mixed, alternative, parallel, digest.
270
// multipart can be mixed, alternative, parallel, digest.
266
// message/rfc822 may also be of interest.
271
// message/rfc822 may also be of interest.
267
272
268
void MimeHandlerMail::walkmime(Rcl::Doc& docout, Binc::MimePart& doc, int depth)
273
void MimeHandlerMail::walkmime(Rcl::Doc& docout, Binc::MimePart& doc,int depth)
269
{
274
{
275
    LOGDEB2(("MimeHandlerMail::walkmime: depth %d\n", depth));
276
    if (depth++ >= maxdepth) {
277
  LOGINFO(("walkmime: max depth (%d) exceeded\n", maxdepth));
278
  return;
279
    }
280
270
    string &out = docout.text;
281
    string &out = docout.text;
271
    if (depth > 5) {
272
  LOGINFO(("walkmime: max depth (5) exceeded\n"));
273
  return;
274
    }
275
282
276
    if (doc.isMultipart()) {
283
    if (doc.isMultipart()) {
277
    LOGDEB2(("walkmime: ismultipart %d subtype '%s'\n", 
284
    LOGDEB2(("walkmime: ismultipart %d subtype '%s'\n", 
278
        doc.isMultipart(), doc.getSubType().c_str()));
285
        doc.isMultipart(), doc.getSubType().c_str()));
279
    // We only handle alternative, related and mixed for now. For
286
    // We only handle alternative, related and mixed for now. For
...
...
281
    // process it. For mixed and related, we process each part.
288
    // process it. For mixed and related, we process each part.
282
    std::vector<Binc::MimePart>::iterator it;
289
    std::vector<Binc::MimePart>::iterator it;
283
    if (!stringicmp("mixed", doc.getSubType()) || 
290
    if (!stringicmp("mixed", doc.getSubType()) || 
284
        !stringicmp("related", doc.getSubType())) {
291
        !stringicmp("related", doc.getSubType())) {
285
        for (it = doc.members.begin(); it != doc.members.end();it++) {
292
        for (it = doc.members.begin(); it != doc.members.end();it++) {
286
        walkmime(docout, *it, depth+1);
293
        walkmime(docout, *it, depth);
287
        }
294
        }
288
    } else if (!stringicmp("alternative", doc.getSubType())) {
295
    } else if (!stringicmp("alternative", doc.getSubType())) {
289
        std::vector<Binc::MimePart>::iterator ittxt, ithtml;
296
        std::vector<Binc::MimePart>::iterator ittxt, ithtml;
290
        ittxt = ithtml = doc.members.end();
297
        ittxt = ithtml = doc.members.end();
291
        int i = 1;
298
        int i = 1;
...
...
304
        else if (!stringlowercmp("text/html", content_type.value)) 
311
        else if (!stringlowercmp("text/html", content_type.value)) 
305
            ithtml = it;
312
            ithtml = it;
306
        }
313
        }
307
        if (ittxt != doc.members.end()) {
314
        if (ittxt != doc.members.end()) {
308
        LOGDEB2(("walkmime: alternative: chose text/plain part\n"))
315
        LOGDEB2(("walkmime: alternative: chose text/plain part\n"))
309
        walkmime(docout, *ittxt, depth+1);
316
        walkmime(docout, *ittxt, depth);
310
        } else if (ithtml != doc.members.end()) {
317
        } else if (ithtml != doc.members.end()) {
311
        LOGDEB2(("walkmime: alternative: chose text/html part\n"))
318
        LOGDEB2(("walkmime: alternative: chose text/html part\n"))
312
        walkmime(docout, *ithtml, depth+1);
319
        walkmime(docout, *ithtml, depth);
313
        }
320
        }
314
    }
321
    }
315
    return;
322
    return;
316
    } 
323
    } 
317
    
324
    
...
...
364
        out += "[" + dispindic + " " + content_type.value + ": ";
371
        out += "[" + dispindic + " " + content_type.value + ": ";
365
    out += filename;
372
    out += filename;
366
    if (m_forPreview)
373
    if (m_forPreview)
367
        out += "]";
374
        out += "]";
368
    out += "\n\n";
375
    out += "\n\n";
369
    processMsg(docout, doc.members[0], depth+1);
376
    processMsg(docout, doc.members[0], depth);
370
    return;
377
    return;
371
    }
378
    }
372
379
373
    // "Simple" part. 
380
    // "Simple" part. 
374
    LOGDEB2(("walkmime: simple  part\n"));
381
    LOGDEB2(("walkmime: simple  part\n"));