~ubuntu-branches/ubuntu/breezy/lurker/breezy

« back to all changes in this revision

Viewing changes to render/attach.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Meurer
  • Date: 2004-09-26 16:27:51 UTC
  • Revision ID: james.westby@ubuntu.com-20040926162751-z1ohcjltv7ojtg6z
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  $Id: attach.cpp,v 1.10 2004/08/19 14:52:29 terpstra Exp $
 
2
 *  
 
3
 *  attach.cpp - Handle a attach/ command
 
4
 *  
 
5
 *  Copyright (C) 2002 - Wesley W. Terpstra
 
6
 *  
 
7
 *  License: GPL
 
8
 *  
 
9
 *  Authors: 'Wesley W. Terpstra' <wesley@terpstra.ca>
 
10
 *  
 
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.
 
14
 *    
 
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.
 
19
 *    
 
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
 
23
 */
 
24
 
 
25
#define _XOPEN_SOURCE 500
 
26
#define _FILE_OFFSET_BITS 64
 
27
 
 
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>
 
35
 
 
36
#include "commands.h"
 
37
#include "Summary.h"
 
38
 
 
39
#include <iostream>
 
40
 
 
41
using std::cout;
 
42
 
 
43
int attach_format_error(const string& param)
 
44
{
 
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."));
 
52
        return 1;
 
53
}
 
54
 
 
55
int attach_no_permission(const string& param)
 
56
{
 
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."));
 
62
        return 1;
 
63
}
 
64
 
 
65
DwEntity& attach_find(DwEntity& e, long& x)
 
66
{
 
67
        // We are the requested entity.
 
68
        if (--x == 0) return e;
 
69
        
 
70
        // if (e.hasHeaders() && 
 
71
        if (e.Headers().HasContentType())
 
72
        {
 
73
                DwMediaType& t = e.Headers().ContentType();
 
74
                switch (t.Type())
 
75
                {
 
76
                case DwMime::kTypeMessage:
 
77
                        if (e.Body().Message())
 
78
                                return attach_find(*e.Body().Message(), x);
 
79
                        break;
 
80
                
 
81
                case DwMime::kTypeMultipart:
 
82
                        for (DwBodyPart* p = e.Body().FirstBodyPart(); p != 0; p = p->Next())
 
83
                        {
 
84
                                DwEntity& o = attach_find(*p, x);
 
85
                                if (x == 0) return o;
 
86
                        }
 
87
                        break;
 
88
                }
 
89
        }
 
90
        
 
91
        return e;
 
92
}
 
93
 
 
94
string unfold_header(const char* hdr)
 
95
{
 
96
        string out;
 
97
        
 
98
        while (*hdr != 0)
 
99
        {
 
100
                if (*hdr == '\r' || *hdr == '\n' || *hdr == '\t')
 
101
                        out += ' ';
 
102
                else    out += *hdr;
 
103
                ++hdr;
 
104
        }
 
105
        
 
106
        return out;
 
107
}
 
108
 
 
109
int handle_attach(const Config& cfg, ESort::Reader* db, const string& param)
 
110
{
 
111
        string::size_type o = param.find('@');
 
112
        long n = atol(param.c_str());
 
113
        
 
114
        if (!cfg.raw_email)
 
115
                return attach_no_permission(param);
 
116
        
 
117
        if (o == string::npos || n <= 0 || 
 
118
            !MessageId::is_full(param.c_str()+o+1))
 
119
                return attach_format_error(param);
 
120
        
 
121
        MessageId id(param.c_str()+o+1);
 
122
        string ok;
 
123
        
 
124
        Summary source(id);
 
125
        if ((ok = source.load(db, cfg)) != "")
 
126
        {
 
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."));
 
131
                return 1;
 
132
        }
 
133
        
 
134
        DwMessage message;
 
135
        if ((ok = source.message(cfg.dbdir, message)) != "")
 
136
        {
 
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?"));
 
142
                return 1;
 
143
        }
 
144
        
 
145
        DwEntity& e = attach_find(message, n);
 
146
        
 
147
        // Cannot cache an attachment because they have strange content-type
 
148
        
 
149
        cout << "Status: 200 OK\r\n"
 
150
             << "Content-Type: ";
 
151
        
 
152
        // if (e.hasHeaders() &&
 
153
        if (e.Headers().HasContentType())
 
154
        {
 
155
                cout << unfold_header(
 
156
                        e.Headers().ContentType().AsString().c_str());
 
157
        }
 
158
        else    cout << "text/plain";
 
159
        
 
160
        cout << "\r\n\r\n";
 
161
        
 
162
        DwString out;
 
163
        // if (e.hasHeaders() && 
 
164
        if (e.Headers().HasContentTransferEncoding())
 
165
        {
 
166
                switch (e.Headers().ContentTransferEncoding().AsEnum())
 
167
                {
 
168
                case DwMime::kCteQuotedPrintable:
 
169
                        DwDecodeQuotedPrintable(e.Body().AsString(), out);
 
170
                        break;
 
171
                        
 
172
                case DwMime::kCteBase64:
 
173
                        DwDecodeBase64(e.Body().AsString(), out);
 
174
                        break;
 
175
                
 
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();
 
182
                        break;
 
183
                }
 
184
                
 
185
        }
 
186
        else
 
187
        {
 
188
                out = e.Body().AsString();
 
189
        }
 
190
        
 
191
        cout.write(out.c_str(), out.length());
 
192
        return 0;
 
193
}