1
/* $Id: attach.cpp,v 1.10 2004/08/19 14:52:29 terpstra Exp $
3
* attach.cpp - Handle a attach/ command
5
* Copyright (C) 2002 - Wesley W. Terpstra
9
* Authors: 'Wesley W. Terpstra' <wesley@terpstra.ca>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; version 2.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#define _XOPEN_SOURCE 500
26
#define _FILE_OFFSET_BITS 64
28
#include <mimelib/message.h>
29
#include <mimelib/headers.h>
30
#include <mimelib/bodypart.h>
31
#include <mimelib/body.h>
32
#include <mimelib/enum.h>
33
#include <mimelib/mediatyp.h>
34
#include <mimelib/utility.h>
43
int attach_format_error(const string& param)
45
cout << "Status: 200 OK\r\n";
46
cout << "Content-Type: text/html\r\n\r\n";
47
cout << error(_("Bad request"), param,
48
_("The given parameter was not of the correct format. "
49
"An attach request must be formatted like: "
50
"attach/id@YYYYMMDD.HHMMSS.hashcode.xml where id "
51
"is the number of the attachment."));
55
int attach_no_permission(const string& param)
57
cout << "Status: 200 OK\r\n";
58
cout << "Content-Type: text/html\r\n\r\n";
59
cout << error(_("Permission Denied"), param,
60
_("Access to mail attachments has been disabled. "
61
"Contact the site administrator if this is a problem."));
65
DwEntity& attach_find(DwEntity& e, long& x)
67
// We are the requested entity.
68
if (--x == 0) return e;
70
// if (e.hasHeaders() &&
71
if (e.Headers().HasContentType())
73
DwMediaType& t = e.Headers().ContentType();
76
case DwMime::kTypeMessage:
77
if (e.Body().Message())
78
return attach_find(*e.Body().Message(), x);
81
case DwMime::kTypeMultipart:
82
for (DwBodyPart* p = e.Body().FirstBodyPart(); p != 0; p = p->Next())
84
DwEntity& o = attach_find(*p, x);
94
string unfold_header(const char* hdr)
100
if (*hdr == '\r' || *hdr == '\n' || *hdr == '\t')
109
int handle_attach(const Config& cfg, ESort::Reader* db, const string& param)
111
string::size_type o = param.find('@');
112
long n = atol(param.c_str());
115
return attach_no_permission(param);
117
if (o == string::npos || n <= 0 ||
118
!MessageId::is_full(param.c_str()+o+1))
119
return attach_format_error(param);
121
MessageId id(param.c_str()+o+1);
125
if ((ok = source.load(db, cfg)) != "")
127
cout << "Status: 200 OK\r\n";
128
cout << "Content-Type: text/html\r\n\r\n";
129
cout << error(_("Database attach source pull failure"), ok,
130
_("The specified message does not exist."));
135
if ((ok = source.message(cfg.dbdir, message)) != "")
137
cout << "Status: 200 OK\r\n";
138
cout << "Content-Type: text/html\r\n\r\n";
139
cout << error(_("MBox read failure"), ok,
140
_("Unable to open message in the mailbox. "
141
"Perhaps it has been deleted or moved?"));
145
DwEntity& e = attach_find(message, n);
147
// Cannot cache an attachment because they have strange content-type
149
cout << "Status: 200 OK\r\n"
152
// if (e.hasHeaders() &&
153
if (e.Headers().HasContentType())
155
cout << unfold_header(
156
e.Headers().ContentType().AsString().c_str());
158
else cout << "text/plain";
163
// if (e.hasHeaders() &&
164
if (e.Headers().HasContentTransferEncoding())
166
switch (e.Headers().ContentTransferEncoding().AsEnum())
168
case DwMime::kCteQuotedPrintable:
169
DwDecodeQuotedPrintable(e.Body().AsString(), out);
172
case DwMime::kCteBase64:
173
DwDecodeBase64(e.Body().AsString(), out);
176
case DwMime::kCteNull:
177
case DwMime::kCteUnknown:
178
case DwMime::kCte7bit:
179
case DwMime::kCte8bit:
180
case DwMime::kCteBinary:
181
out = e.Body().AsString();
188
out = e.Body().AsString();
191
cout.write(out.c_str(), out.length());