/* Copyright (c) 2017, Computer History Museum All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MIMESTORE_H #define MIMESTORE_H /************************************************************************ * types ************************************************************************/ #define STRUCTURE(x) typedef struct x x, *x##Ptr, **x##Handle STRUCTURE(MStoreMailDBHeader); STRUCTURE(MStoreTOCFileHeader); STRUCTURE(EudoraMessInstanceID); STRUCTURE(I4UIDPlus); STRUCTURE(MStoreSummary); STRUCTURE(MStoreIDDBHeader); STRUCTURE(MStoreIDDBBlock); STRUCTURE(MStoreInfo); STRUCTURE(MStoreMemIDDB); STRUCTURE(MStoreBox); STRUCTURE(MStoreBlockHeader); STRUCTURE(MStoreVersion); STRUCTURE(MStoreSubFile); /************************************************************************ * On-Disk Constants and Structures ************************************************************************/ /************************************************************************ * Version Number ************************************************************************/ #define kMStoreMajorVersion 1 #define kMStoreMinorVersion 0 /************************************************************************ * a 47-char string ************************************************************************/ typedef unsigned char Str47[48]; /************************************************************************ * File types ************************************************************************/ typedef enum { kMStoreMailDBMagic = 'MlDb', kMStoreMailDBTerm = 'bDlM', kMStoreMailFileType = 'EuMB', kMStoreIDDBFileType = 'EuID', kMStoreTOCFileType = 'EuTC', kMStoreInfoFileType = 'EuIf', kMStoreDummyFileType = 0 } MStoreFileTypeEnum; /************************************************************************ * Version number ************************************************************************/ struct MStoreVersion { short majorVersion; short minorVersion; }; /************************************************************************ * MailDB header ************************************************************************/ struct MStoreMailDBHeader { unsigned long magic; // magic number for MailDB file MStoreVersion highVersion; // highest version # of file ever written MStoreVersion lastVersion; // last version # of file written unsigned long modSeconds; // mod seconds of last time written }; /************************************************************************ * MStoreBlockHeader - block header in MailDB file ************************************************************************/ struct MStoreBlockHeader { long magic; long type; long id; long size; long refCount; long attrSize; }; /************************************************************************ * Types for blocks ************************************************************************/ typedef enum { kMStoreFreeType = 'Free', // Free block kMStoreMessageType = 'Mess', // Message descriptor kMStoreContHeaderType = 'Hdrs', // Headers of a content kMStoreContBodyType = 'Body', // Body of a content kMStoreContentType = 'Cont', // Headers and body of content in one piece kMStoreStubType = 'Stub', // POP3 message stub kMStoreI4EnvelopeType = 'I4Ev', // IMAP4 message envelope kMStoreI4Structuretype = 'I4St', // IMAP4 bodystructure kMStoreTerminator = 'tErM', // block terminator; not really a block type... kMStoreDummyType = 0 } MStoreBlockTypeEnum; /************************************************************************ * Types for attributes ************************************************************************/ typedef enum { // ID's kMStorePOP3IIDAttr = 'POP3', // POP3 message instance id kMStoreMessageIIDAttr = 'MIID', // mailstore message instance id kMStoreMessageIDAttr = 'MsID', // Hash of message-id field kMStoreI4MailMessIIDAttr = 'I4MM', // IMAP4 Mailbox-message instance id kMStoreI4MessIIDAttr = 'I4ID', // IMAP4 Message instance id kMStoreI4MessINameAttr = 'I4MN', // IMAP4 Message instance name kMStoreI4ContINameAttr = 'I4CN', // IMAP4 Content instance name // MIME Stuff kMStoreMIMECTAttr = 'MICT', // Content-Type parameter kMStoreMIMESTAttr = 'MIST', // Content-Subtype parameter kMStoreMIMECTParamAttr = 'MICP', // Content-type parameter (name=value) kMStoreMIMECDispAttr = 'MICD', // Content-Disposition kMStoreMIMECDispParamAttr = 'MIDP', // Content-Disposition parameter (name=value) // Internal DB stuff kMStoreReferencedAttr = 'Refr', // Block that references this one kMStoreFlagsAttr = 'Flag', // Flags // Misc kMStoreComputedHashAttr = 'CHsh', // Hash algorithm & value computed by us kMStoreContentSizeAttr = 'CSiz', // Size of content kMStoreDummyAttr = 0 } MStoreAttributeEnum; #define kMStoreContentID kMStoreMessageID // same as message-id, only content-id /************************************************************************ * Content flags ************************************************************************/ typedef enum { kMStoreFlagOriginal, // content has not been transformed in any way kMStoreFlagNotUTF8, // content is not in UTF-8 kMStoreFlagMacintosh, // message came from Mac Eudora <4.0 kMStoreFlagWindows, // message came from Win Eudora <4.0 kMStoreFlagNotMIME, // message is non-MIME kMStoreFlagStub, // partially downloaded kMStoreFlagErrors, // content had errors during download kMStoreFlagWipe, // content should be wiped after being freed kMStoreFlagDummy } MStoreTextFlagsEnum; /************************************************************************ * Morsels ************************************************************************/ typedef enum { kMStorePartMorsel = 'Part', // alternate forms of a single content kMStoreMultiMorsel = 'Mult', // a multipart content kMStoreDummyMorsel = 0 } MStoreMorselEnum; /************************************************************************ * TOC File Header ************************************************************************/ struct MStoreTOCFileHeader { MStoreVersion highVersion; // highest version # of file ever written MStoreVersion lastVersion; // last version # of file written unsigned long modSeconds; // mod seconds of last time written unsigned long sumSize; // size of summaries unsigned long sumCount; // # of summaries }; /************************************************************************ * Message instance id ************************************************************************/ struct EudoraMessInstanceID { unsigned long mailboxID; unsigned long messageID; }; /************************************************************************ * I4UIDPlus - IMAP4 uid+; uidvalidity+uid ************************************************************************/ struct I4UIDPlus { unsigned long i4UIDValidity; unsigned long i4UID; }; /************************************************************************ * Message Summary ************************************************************************/ struct MStoreSummary { EudoraMessInstanceID mIID; // Where is it stored? uLong mid; // Hash of message-id header uLong size; // Content size, for user's benefit uLong seconds; // Message date, in seconds since 12am 1 Jan 1970 GMT short zone; // Message original timezone, in seconds short pad; // unused Byte state; // unread, read, etc Byte priority; // current user-assigned priority Byte origPriority; // priority message came in with Byte label; // user-assigned message label uLong flags[2]; // message flags; see below Rect position; // position of window uLong personality; // personality id I4UIDPlus i4UIDPlus; // IMAP4 UID+; interesting only if in synced mailbox Str31 from; // Human string for sender of message Str47 subject; // Human string for subject of message }; /************************************************************************ * summary flags * number is bit count from lowest bit of mFlags[1] up to high bit of mFlags[1] ************************************************************************/ typedef enum { kSumFlagMDN, // user has requested an MDN for this message (outgoing) kSumFlagDSN, // user has requested a DSN for this message (outgoing) kSumFlagPartial, // only part of the message has been downloaded kSumFlagOnServer, // this message still exists on a server kSumFlagEncodingErrors, // encoding errors were found while transferring kSumFlagOutgoing, // this is an outgoing message kSumFlagZoomed, // window was in zoomed state when closed kSumFlagReport, // message is an MDN or DSN report kSumFlagWipe, // bits should be wiped when message moved or deleted kSumFlagEdited, // user has changed this message kSumFlagWeirdReply, // message has reply-to different from from: kSumFlagFormatBar, // message has format bar (outgoing) kSumFlagWordWrap, // word wrap when sending (outgoing) kSumFlagKeepCopy, // keep a copy after sending (outgoing) kSumFlagLocked, // user has locked the message in this mailbox kSumFlagSpooledAttachments, // message has spool folder associated with it kSumFlagBodyAllowEncoding, // user says ok to encode this message body kSumFlagBodyForceEncoding, // user says body of message must be encoded kSumFlagBodyWordWrap, // user says word wrap body of message kSumFlagTextAllowEncoding, // user says ok to encode text attachments kSumFlagTextForceEncoding, // user says text attachments must be encoded kSumFlagTextWordWrap, // user says word wrap text attachments kSumFlagAttach1, // low bit of attachment type kSumFlagAttach2, // middle bit of attachment type kSumFlagAttach3, // high bit of attachment type kSumFlagResourceFork, // include resource fork with attachments kSumDummy } MStoreSummaryFlagEnum; /************************************************************************ * IDDB File header ************************************************************************/ struct MStoreIDDBHeader { OSType iddbMagic; // magic number MStoreVersion highVersion; // highest version # of file ever written MStoreVersion lastVersion; // last version # of file written unsigned long modSeconds; // mod seconds of last time written }; /************************************************************************ * IDDB Blocks ************************************************************************/ struct MStoreIDDBBlock { unsigned long blockID; unsigned long offset; unsigned long size; }; /************************************************************************ * Info file ************************************************************************/ struct MStoreInfo { Str255 name; }; /************************************************************************ * In-Memory Constants and Structures ************************************************************************/ /************************************************************************ * IDDB in-memory version ************************************************************************/ struct MStoreMemIDDB { MStoreIDDBBlock block; long dirty:1; long locked:1; }; /************************************************************************ * SubFile - manage the aspects of a subfile of a mailbox ************************************************************************/ typedef enum {msfcCreate,msfcOpen,msfcFlush,msfcClose,msfcCloseHard,msfcDestroy} MSSubCallEnum; struct MStoreSubFile { short refN; short fileNameID; OSType fileType; OSErr (*func)(MSSubCallEnum selector,MStoreBoxHandle boxH); long dirty:1; }; /************************************************************************ * Mailbox ************************************************************************/ struct MStoreBox { short type; // In/Out/Trash or regular short refCount; // number of references short locked; // somebody is using it FSSpec spec; // Spec (could be alias) of the folder VDId dir; // Volume and directory containing the mailbox MStoreSubFile subs[4]; // subfile info StackHandle iddb; // The IDDB for this mailbox StackHandle summaries; // message summaries MStoreInfo info; // The info file MStoreMailDBHeader mailDBHeader; // Header for maildb file uLong mailDBModTime; }; typedef enum {mssfMailDB,mssfIDDB,mssfTOC,mssfInfo,mssfLimit} MSSubFileEnum; // indices into subfile array /************************************************************************ * Functions ************************************************************************/ OSErr MSCreateMailbox(FSSpecPtr spec,MStoreBoxHandle *boxH); OSErr MSOpenMailbox(FSSpecPtr spec,MStoreBoxHandle *boxH); OSErr MSFlushMailbox(MStoreBoxHandle boxH); OSErr MSCloseMailbox(MStoreBoxHandle boxH,Boolean force); // utilities for other mime store stuff OSErr MSCreateSubFile(MStoreBoxHandle boxH,MSSubFileEnum file); OSErr MSOpenSubFile(MStoreBoxHandle boxH,MSSubFileEnum file); OSErr MSCloseSubFile(MStoreBoxHandle boxH,MSSubFileEnum file); OSErr MSDestroySubFile(MStoreBoxHandle boxH,MSSubFileEnum file); #define JAN11970 2082844800 #define MStoreDateTime() (GMTDateTime()-JAN11970) // version utilities #define MStoreCurrentVersion(v) do{(v)->majorVersion = kMStoreMajorVersion; (v)->minorVersion = kMStoreMinorVersion;}while(0) #define MStoreCompatibleVersion(v) ((v)->majorVersion <= kMStoreMajorVersion) #define MStoreOlderVersion(v) ((v)->majorVersionmajorVersion==kMStoreMajorVersion && (v)->minorVersion