00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "r_saved_message.h"
00025 #include "record-internal.h"
00026 #include "protocol.h"
00027 #include "protostructs.h"
00028 #include "data.h"
00029 #include "time.h"
00030 #include "error.h"
00031 #include "endian.h"
00032 #include <ostream>
00033 #include <iomanip>
00034 #include <time.h>
00035 #include <stdexcept>
00036
00037 #define __DEBUG_MODE__
00038 #include "debug.h"
00039
00040 using namespace std;
00041 using namespace Barry::Protocol;
00042
00043 namespace Barry {
00044
00045
00046
00047
00048
00049
00050 #define SEMFC_TO 0x01 // can occur multiple times
00051 #define SEMFC_CC 0x02 // ditto
00052 #define SEMFC_BCC 0x03 // ditto
00053 #define SEMFC_SENDER 0x04
00054 #define SEMFC_FROM 0x05
00055 #define SEMFC_REPLY_TO 0x06
00056 #define SEMFC_SUBJECT 0x0b
00057 #define SEMFC_BODY 0x0c
00058 #define SEMFC_ATTACHMENT 0x16
00059 #define SEMFC_RECORDID 0x4b
00060 #define SEMFC_END 0xffff
00061
00062 #define PRIORITY_MASK 0x003f
00063 #define PRIORITY_HIGH 0x0008
00064 #define PRIORITY_LOW 0x0002
00065
00066 #define SENSITIVE_MASK 0xff80
00067 #define SENSITIVE_CONFIDENTIAL 0x0100
00068 #define SENSITIVE_PERSONAL 0x0080
00069 #define SENSITIVE_PRIVATE 0x0040 // actual pattern is 0x00C0
00070
00071 #define MESSAGE_READ 0x0800
00072 #define MESSAGE_REPLY 0x0001
00073 #define MESSAGE_SAVED 0x0002
00074 #define MESSAGE_FORWARD 0x0008
00075 #define MESSAGE_TRUNCATED 0x0020
00076 #define MESSAGE_SAVED_DELETED 0x0080
00077
00078 FieldLink<SavedMessage> SavedMessageFieldLinks[] = {
00079 { SEMFC_TO, "To", 0, 0, 0, &SavedMessage::To, 0 },
00080 { SEMFC_CC, "Cc", 0, 0, 0, &SavedMessage::Cc, 0 },
00081 { SEMFC_BCC, "Bcc", 0, 0, 0, &SavedMessage::Bcc, 0 },
00082 { SEMFC_SENDER, "Sender", 0, 0, 0, &SavedMessage::Sender, 0 },
00083 { SEMFC_FROM, "From", 0, 0, 0, &SavedMessage::From, 0 },
00084 { SEMFC_REPLY_TO, "ReplyTo", 0, 0, 0, &SavedMessage::ReplyTo, 0 },
00085 { SEMFC_SUBJECT, "Subject", 0, 0, &SavedMessage::Subject, 0, 0 },
00086 { SEMFC_BODY, "Body", 0, 0, &SavedMessage::Body, 0, 0 },
00087 { SEMFC_ATTACHMENT, "Attachment", 0, 0, &SavedMessage::Attachment, 0, 0 },
00088 { SEMFC_END, "End of List", 0, 0, 0, 0, 0 }
00089 };
00090
00091 SavedMessage::SavedMessage()
00092 {
00093 Clear();
00094 }
00095
00096 SavedMessage::~SavedMessage()
00097 {
00098 }
00099
00100 const unsigned char* SavedMessage::ParseField(const unsigned char *begin,
00101 const unsigned char *end)
00102 {
00103 const CommonField *field = (const CommonField *) begin;
00104
00105
00106 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00107 if( begin > end )
00108 return begin;
00109
00110 if( !btohs(field->size) )
00111 return begin;
00112
00113
00114 for( FieldLink<SavedMessage> *b = SavedMessageFieldLinks;
00115 b->type != SEMFC_END;
00116 b++ )
00117 {
00118 if( b->type == field->type ) {
00119 if( b->strMember ) {
00120
00121 std::string &s = this->*(b->strMember);
00122 s = ParseFieldString(field);
00123 return begin;
00124 }
00125 else if( b->addrMember ) {
00126
00127
00128 const char *fa = (const char*)field->u.addr.addr;
00129 std::string dual(fa, btohs(field->size) - sizeof(field->u.addr.unknown));
00130
00131
00132 EmailAddress &a = this->*(b->addrMember);
00133 a.Name = dual.c_str();
00134
00135
00136 a.Email = dual.c_str() + a.Name.size() + 1;
00137 return begin;
00138 }
00139 }
00140 }
00141
00142
00143 switch( field->type )
00144 {
00145 case SEMFC_RECORDID:
00146 MessageRecordId = btohl(field->u.uint32);
00147 return begin;
00148 }
00149
00150
00151 UnknownField uf;
00152 uf.type = field->type;
00153 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00154 Unknowns.push_back(uf);
00155
00156 return begin;
00157 }
00158
00159 void SavedMessage::ParseHeader(const Data &data, size_t &offset)
00160 {
00161 Protocol::CheckSize(data, offset + MESSAGE_RECORD_HEADER_SIZE);
00162
00163 MAKE_RECORD(const Barry::Protocol::MessageRecord, mr, data, offset);
00164
00165
00166 MessagePriority = NormalPriority;
00167
00168 uint16_t priority = btohs(mr->priority);
00169 if( priority & PRIORITY_MASK ) {
00170 if( priority & PRIORITY_HIGH ) {
00171 MessagePriority = HighPriority;
00172 }
00173 else if( priority & PRIORITY_LOW ) {
00174 MessagePriority = LowPriority;
00175 }
00176 else
00177 MessagePriority = UnknownPriority;
00178 }
00179
00180 MessageSensitivity = NormalSensitivity;
00181 if( priority & SENSITIVE_MASK ) {
00182 if(( priority & SENSITIVE_CONFIDENTIAL ) == SENSITIVE_CONFIDENTIAL ) {
00183 MessageSensitivity = Confidential;
00184 }
00185 else if(( priority & SENSITIVE_PRIVATE ) == SENSITIVE_PRIVATE ) {
00186 MessageSensitivity = Private;
00187 }
00188 else if(( priority & SENSITIVE_PERSONAL ) == SENSITIVE_PERSONAL ) {
00189 MessageSensitivity = Personal;
00190 }
00191 else
00192 MessageSensitivity = UnknownSensitivity;
00193 }
00194
00195 if( mr->inReplyTo )
00196 MessageReplyTo = btohl(mr->inReplyTo);
00197
00198
00199 uint32_t flags = btohl(mr->flags);
00200 if( !( flags & MESSAGE_READ ))
00201 MessageRead = true;
00202
00203 if(( flags & MESSAGE_REPLY ) == MESSAGE_REPLY )
00204 MessageReply = true;
00205
00206 if( !( flags & MESSAGE_TRUNCATED ))
00207 MessageTruncated = true;
00208
00209
00210 if( !( flags & MESSAGE_SAVED ))
00211 MessageSaved = true;
00212 if( !( flags & MESSAGE_SAVED_DELETED ))
00213 MessageSavedDeleted = true;
00214
00215 MessageDateSent = Message2Time(mr->dateSent, mr->timeSent);
00216 MessageDateReceived = Message2Time(mr->dateReceived, mr->timeReceived);
00217
00218 offset += MESSAGE_RECORD_HEADER_SIZE;
00219 }
00220
00221 void SavedMessage::ParseFields(const Data &data, size_t &offset)
00222 {
00223 const unsigned char *finish = ParseCommonFields(*this,
00224 data.GetData() + offset, data.GetData() + data.GetSize());
00225 offset += finish - (data.GetData() + offset);
00226 }
00227
00228 void SavedMessage::BuildHeader(Data &data, size_t &offset) const
00229 {
00230 throw std::logic_error("SavedMessage::BuildHeader not yet implemented");
00231 }
00232
00233 void SavedMessage::BuildFields(Data &data, size_t &offset) const
00234 {
00235 throw std::logic_error("SavedMessage::BuildFields not yet implemented");
00236 }
00237
00238 void SavedMessage::Clear()
00239 {
00240 From.clear();
00241 To.clear();
00242 Cc.clear();
00243 Bcc.clear();
00244 Sender.clear();
00245 ReplyTo.clear();
00246 Subject.clear();
00247 Body.clear();
00248 Attachment.clear();
00249
00250 MessageRecordId = 0;
00251 MessageReplyTo = 0;
00252 MessageDateSent = 0;
00253 MessageDateReceived = 0;
00254 MessageTruncated = false;
00255 MessageRead = false;
00256 MessageReply = false;
00257 MessageSaved = false;
00258 MessageSavedDeleted = false;
00259 Unknowns.clear();
00260 }
00261
00262
00263 void SavedMessage::Dump(std::ostream &os) const
00264 {
00265 static const char *MessageImportance[] =
00266 { "Low", "Normal", "High", "Unknown Priority" };
00267 static const char *MessageSensitivityString[] =
00268 { "Normal", "Personal", "Private", "Confidential", "Unknown Sensivity" };
00269
00270 os << "From " << (From.Email.size() ? From.Email.c_str() : "unknown")
00271 << " " << ctime( &MessageDateSent );
00272 os << "X-Record-ID: (" << setw(8) << std::hex << MessageRecordId << ")\n";
00273 if( MessageReplyTo )
00274 os << "X-rim-org-msg-ref-id: " << std::dec << MessageReplyTo << "\n";
00275 if( MessageSaved )
00276 os << "Message Status: Saved\n";
00277 else if( MessageRead )
00278 os << "Message Status: Opened\n";
00279 if( MessagePriority != NormalPriority )
00280 os << "Importance: " << MessageImportance[MessagePriority] << "\n";
00281 if( MessageSensitivity != NormalSensitivity )
00282 os << "Sensitivity: " << MessageSensitivityString[MessageSensitivity] << "\n";
00283 os << "Date: " << ctime(&MessageDateSent);
00284 os << "From: " << From << "\n";
00285 if( To.Email.size() )
00286 os << "To: " << To << "\n";
00287 if( Cc.Email.size() )
00288 os << "Cc: " << Cc << "\n";
00289 if( Bcc.Email.size() )
00290 os << "Bcc: " << Bcc << "\n";
00291 if( Sender.Email.size() )
00292 os << "Sender: " << Sender << "\n";
00293 if( ReplyTo.Email.size())
00294 os << "Reply To: " << ReplyTo << "\n";
00295 if( Subject.size() )
00296 os << "Subject: " << Subject << "\n";
00297 os << "\n";
00298 for( std::string::const_iterator i = Body.begin();
00299 i != Body.end() && *i;
00300 i++)
00301 {
00302 if( *i == '\r' )
00303 os << '\n';
00304 else
00305 os << *i;
00306 }
00307 os << "\n";
00308 if( Attachment.size() )
00309 os << "Attachments: " << Attachment << "\n";
00310
00311 os << Unknowns;
00312 os << "\n\n";
00313 }
00314
00315
00316 }
00317