1
/* $Id: Summary.cpp,v 1.2 2004/08/24 21:52:39 terpstra Exp $
3
* Summary.cpp - Helper which can load a message given MessageId
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>
35
#include <XmlEscape.h>
45
string Summary::load(Reader* r, const Config& cfg)
47
// Use the prefix limited search
48
auto_ptr<Walker> w(r->seek(LU_SUMMARY + id_.raw(), "", Forward));
50
// This will only walk records matching this id
53
while ((ok = w->advance()) != -1)
55
if (w->key.length() < 1 + 8 + 1)
56
return "invalid mbox entry -- way too short";
58
// We use this for getting an unsigned value below.
59
const unsigned char* k = (const unsigned char*)w->key.c_str()+1+8;
61
// read all the values
64
case LU_MESSAGE_DELETED:
68
case LU_MESSAGE_AUTHOR_EMAIL:
69
author_email_ = w->key.substr(1+8+1, string::npos);
72
string::size_type x = author_email_.find('@');
73
if (x != string::npos) author_email_.resize(x);
74
if (!author_name_.length()) author_name_ = author_email_;
79
case LU_MESSAGE_AUTHOR_NAME:
80
if (w->key.length() > 1+8+1)
81
author_name_ = w->key.substr(1+8+1, string::npos);
84
case LU_MESSAGE_SUBJECT:
85
subject_ = w->key.substr(1+8+1, string::npos);
89
if (w->key.length() < 1+8+1+1+12)
90
return "invalid mbox entry -- too short";
92
//!!! could be more careful about corrupt dbs here
95
mbox_ = (const char*)k; // null terminated
101
for (i = 0; i < 8; ++i)
107
for (i = 8; i < 12; ++i)
113
mboxs_.insert(mbox_);
117
return "unknown mbox summary control code";
122
return "not in a mailbox";
124
if (ok == -1 && errno != 0)
125
return string("Walker::advance:") + strerror(errno);
130
string Summary::message(const string& dbdir, DwMessage& message) const
132
string name = dbdir + "/" + mbox_;
133
int fd = open(name.c_str(), O_RDONLY);
135
return name + ":open:" + strerror(errno);
137
if (lseek(fd, offset_, SEEK_SET) != offset_)
140
return name + ":lseek:" + strerror(errno);
143
gzFile gzf = gzdopen(fd, "rb");
147
return name + ":gzdopen:" + strerror(errno);
152
unsigned long want = length_;
157
if (want < sizeof(buf))
159
else get = sizeof(buf);
161
if (gzread(gzf, buf, get) != get)
164
return name + ":gzread:" + strerror(errno);
167
str.append(buf, get);
171
gzclose(gzf); // also closes fd
173
message.FromString(str);
179
ostream& operator << (ostream& o, const Summary& s)
182
<< "<id>" << s.id().serialize() << "</id>"
183
<< "<timestamp>" << s.id().timestamp() << "</timestamp>";
188
if (s.subject().length() > 0)
189
o << "<subject>" << xmlEscape << s.subject() << "</subject>";
192
if (s.author_email().length() > 0)
193
o << " address=\"" << xmlEscape << s.author_email() << "\"";
194
if (s.author_name().length() > 0)
195
o << " name=\"" << xmlEscape << s.author_name() << "\"";