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.29 2007-01-17 13:53:40 dockes Exp $ (C) 2005 J.F.Dockes";
2
static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.30 2007-10-17 11:40:35 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
...
...
133
    m_idx++;
133
    m_idx++;
134
    m_havedoc = m_idx < (int)m_attachments.size();
134
    m_havedoc = m_idx < (int)m_attachments.size();
135
    return res;
135
    return res;
136
}
136
}
137
137
138
// Decode according to content transfer encoding
138
// Decode according to content transfer encoding. May actually do nothing,
139
static bool decodeBody(const string& cte, const string& body, string& decoded,
139
// which will be indicated by the *respp argument pointing to the original 
140
             const string** respp)
140
// text on exit
141
static bool decodeBody(const string& cte, // Content transfer encoding
142
             const string& body, // Source text
143
             string& decoded,   // Decoded text if actual decoding
144
             const string** respp // Decoding Indicator 
145
             )
141
{
146
{
142
    // By default, there is no encoding (7bit,8bit,raw). Also in case of 
147
    // By default, there is no encoding (7bit,8bit,raw). Also in case of 
143
    // decoding error
148
    // decoding error
144
    *respp = &body;
149
    *respp = &body;
145
150
146
    if (!stringlowercmp("quoted-printable", cte)) {
151
    if (!stringlowercmp("quoted-printable", cte)) {
147
    if (!qp_decode(body, decoded)) {
152
    if (!qp_decode(body, decoded)) {
148
        LOGERR(("decodeBody: quoted-printable decoding failed !\n"));
153
        LOGERR(("decodeBody: quoted-printable decoding failed !\n"));
154
      LOGDEB(("      Body: \n%s\n", body.c_str()));
149
        return false;
155
        return false;
150
    }
156
    }
151
    *respp = &decoded;
157
    *respp = &decoded;
152
    } else if (!stringlowercmp("base64", cte)) {
158
    } else if (!stringlowercmp("base64", cte)) {
153
    if (!base64_decode(body, decoded)) {
159
    if (!base64_decode(body, decoded)) {
160
      // base64 encoding errors are actually relatively common
154
        LOGERR(("decodeBody: base64 decoding failed !. body [%s]\n", 
161
        LOGERR(("decodeBody: base64 decoding failed !\n"));
155
          body.c_str()));
162
      LOGDEB(("      Body: \n%s\n", body.c_str()));
156
        return false;
163
        return false;
157
    }
164
    }
158
    *respp = &decoded;
165
    *respp = &decoded;
159
    }
166
    }
160
    return true;
167
    return true;
...
...
169
    m_havedoc = false;
176
    m_havedoc = false;
170
    return false;
177
    return false;
171
    }
178
    }
172
    MHMailAttach *att = m_attachments[m_idx];
179
    MHMailAttach *att = m_attachments[m_idx];
173
180
174
    LOGDEB1(("processAttach:content-type: %s\n", att->m_contentType.c_str()));
175
    m_metaData["mimetype"] = att->m_contentType;
181
    m_metaData["mimetype"] = att->m_contentType;
176
    m_metaData["charset"] = att->m_charset;
182
    m_metaData["charset"] = att->m_charset;
177
    m_metaData["filename"] = att->m_filename;
183
    m_metaData["filename"] = att->m_filename;
184
    // Change the title to something helpul
185
    m_metaData["title"] = att->m_filename + "  (" + m_subject + ")";
186
    LOGDEB1(("  processAttach:ct [%s] cs [%s] fn [%s]\n", 
187
      att->m_contentType.c_str(),
188
      att->m_charset.c_str(),
189
      att->m_filename.c_str()));
178
190
179
    m_metaData["content"] = "";
191
    m_metaData["content"] = "";
180
    string& body = m_metaData["content"];
192
    string& body = m_metaData["content"];
181
    att->m_part->getBody(body, 0, att->m_part->bodylength);
193
    att->m_part->getBody(body, 0, att->m_part->bodylength);
182
    string decoded;
194
    string decoded;
...
...
184
    if (!decodeBody(att->m_contentTransferEncoding, body, decoded, &bdp)) {
196
    if (!decodeBody(att->m_contentTransferEncoding, body, decoded, &bdp)) {
185
    return false;
197
    return false;
186
    }
198
    }
187
    if (bdp != &body)
199
    if (bdp != &body)
188
    body = decoded;
200
    body = decoded;
201
202
    // Special case for text/plain content. Internfile should deal
203
    // with this but it expects text/plain to be utf-8 already, so we
204
    // handle the transcoding if needed
205
    if (m_metaData["mimetype"] == "text/plain" && 
206
  stringicmp(m_metaData["charset"], "UTF-8")) {
207
  string utf8;
208
  if (!transcode(body, utf8, m_metaData["charset"], "UTF-8")) {
209
      LOGERR(("  processAttach: transcode to utf-8 failed "
210
          "for charset [%s]\n", m_metaData["charset"].c_str()));
211
      // Just let it through and hope for the best...
212
  } else {
213
      body = utf8;
214
  }
215
    }
216
217
    // Ipath
189
    char nbuf[10];
218
    char nbuf[10];
190
    sprintf(nbuf, "%d", m_idx);
219
    sprintf(nbuf, "%d", m_idx);
191
    m_metaData["ipath"] = nbuf;
220
    m_metaData["ipath"] = nbuf;
221
192
    return true;
222
    return true;
193
}
223
}
194
224
195
// Transform a single message into a document. The subject becomes the
225
// Transform a single message into a document. The subject becomes the
196
// title, and any simple body part with a content-type of text or html
226
// title, and any simple body part with a content-type of text or html
...
...
240
    }
270
    }
241
    text += string("Date: ") + transcoded + string("\n");
271
    text += string("Date: ") + transcoded + string("\n");
242
    }
272
    }
243
    if (doc->h.getFirstHeader("Subject", hi)) {
273
    if (doc->h.getFirstHeader("Subject", hi)) {
244
    rfc2047_decode(hi.getValue(), transcoded);
274
    rfc2047_decode(hi.getValue(), transcoded);
245
    if (depth == 1)
275
    if (depth == 1) {
246
        m_metaData["title"] = transcoded;
276
        m_metaData["title"] = transcoded;
277
      m_subject = transcoded;
278
  }
247
    text += string("Subject: ") + transcoded + string("\n");
279
    text += string("Subject: ") + transcoded + string("\n");
248
    }
280
    }
249
    text += '\n';
281
    text += '\n';
250
282
251
    LOGDEB2(("MimeHandlerMail::processMsg:ismultipart %d mime subtype '%s'\n",
283
    LOGDEB2(("MimeHandlerMail::processMsg:ismultipart %d mime subtype '%s'\n",
...
...
404
    if (doc->h.getFirstHeader("Content-Transfer-Encoding", hi)) {
436
    if (doc->h.getFirstHeader("Content-Transfer-Encoding", hi)) {
405
    cte = hi.getValue();
437
    cte = hi.getValue();
406
    } 
438
    } 
407
439
408
    // If the Content-Disposition is not inline, we treat it as
440
    // If the Content-Disposition is not inline, we treat it as
409
    // attachment, as per rfc2183. We don't process attachments
441
    // attachment, as per rfc2183. 
410
    // for now, except for indexing/displaying the file name
411
    // If it is inline but not text or html, same thing.
442
    // If it is inline but not text or html, same thing.
412
    if (stringlowercmp("inline", content_disposition.value) ||
443
    if (stringlowercmp("inline", content_disposition.value) ||
413
    (stringlowercmp("text/plain", content_type.value) && 
444
    (stringlowercmp("text/plain", content_type.value) && 
414
     stringlowercmp("text/html", content_type.value)) ) {
445
     stringlowercmp("text/html", content_type.value)) ) {
415
    if (!filename.empty()) {
446
    if (!filename.empty()) {
...
...
419
        out += filename;
450
        out += filename;
420
        if (m_forPreview)
451
        if (m_forPreview)
421
        out += "]";
452
        out += "]";
422
        out += "\n\n";
453
        out += "\n\n";
423
    }
454
    }
424
  LOGDEB(("walkmime: pushing attchmnt fn [%s]\n", filename.c_str()));
425
    MHMailAttach *att = new MHMailAttach;
455
    MHMailAttach *att = new MHMailAttach;
426
    if (att == 0) {
456
    if (att == 0) {
427
        LOGERR(("Out of memory\n"));
457
        LOGERR(("Out of memory\n"));
428
        return;
458
        return;
429
    }
459
    }
...
...
431
    stringtolower(att->m_contentType);
461
    stringtolower(att->m_contentType);
432
    att->m_filename = filename;
462
    att->m_filename = filename;
433
    att->m_charset = charset;
463
    att->m_charset = charset;
434
    att->m_contentTransferEncoding = cte;
464
    att->m_contentTransferEncoding = cte;
435
    att->m_part = doc;
465
    att->m_part = doc;
466
  LOGDEB(("walkmime: attachmnt: ct [%s] cte [%s] cs [%s] fn [%s]\n", 
467
      att->m_contentType.c_str(),
468
      att->m_contentTransferEncoding.c_str(),
469
      att->m_charset.c_str(),
470
      filename.c_str()));
436
    m_attachments.push_back(att);
471
    m_attachments.push_back(att);
437
    return;
472
    return;
438
    }
473
    }
439
474
440
    // We are dealing with an inline part of text/plain or text/html type
475
    // We are dealing with an inline part of text/plain or text/html type