/* 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. */ /* Copyright (c) 1998 by QUALCOMM Incorporated */ //must have already included imapnetlib.h /********************************************************************** * imapDownload.c * * This file contains the functions that download messages and * message bits from the server. **********************************************************************/ #ifndef IMAPDOWNLOAD_H #define IMAPDOWNLOAD_H // resource where we put IMAP index #define INDEX_RES_TYPE 'IIND' #define INDEX_RES_ID 128 // special values of offset field in summary #define imapNeedToDownload -1 // flags for special header combinations typedef enum { kNone = 0, kBody, kAnyRecipient, kAllHeaders, kAnyWhere } HeaderCombEnum; // flags to tell empty trash routine what to do typedef enum { kEmptyActiveTrashes = 0, kEmptyAutoCheckTrashes, kEmptyAllTrashes } IMAPEmptyTrashEnum; // UIDNode struct. Used for lists of UIDs. typedef struct UIDNode UIDNode, *UIDNodePtr, **UIDNodeHandle; struct UIDNode { // uid of message unsigned long uid; // flags unsigned long l_seen:1; unsigned long l_deleted:1; unsigned long l_flagged:1; unsigned long l_answered:1; unsigned long l_draft:1; unsigned long l_recent:1; unsigned long l_IsNew:1; unsigned long l_sent:1; unsigned long unUsed:8; unsigned long boxIndex:16; // used for IMAP searches unsigned long size; // next UIDNodeHandle next; }; // IndexStruct. Used to locate messages within a temporary IMAP message file typedef struct IndexStruct IndexStruct, *IndexStructPtr; struct IndexStruct { unsigned long uid; long offset; long length; }; // AttachmentStubStruct. Used to save enough information to fecth an attachment later typedef struct AttachmentStubStruct AttachmentStubStruct, *AttachmentStubPtr, **AttachmentStubHandle; struct AttachmentStubStruct { unsigned long persID; // personality ID of owning personality unsigned long uid; // uid of message char section[255]; // section string unsigned long sizeBytes; // body size in bytes unsigned long sizeLines; // body size in lines }; // IMAPSCStruct - one for each header/value pair to be searched typedef struct IMAPSCStruct IMAPSCStruct, *IMAPSCPtr, **IMAPSCHandle; struct IMAPSCStruct { Str255 string; // String to search for HeaderCombEnum headerCombination; // nothing special, body, or all headers short headerName; // string id of header to search }; // IMAPSResultStruct - structure returned for each match typedef struct IMAPSResultStruct IMAPSResultStruct, *IMAPSResultPtr, **IMAPSResultHandle; struct IMAPSResultStruct { short box; // index into BoxCount of match long uidHash; // the matching summary }; // special value indicating all messages in lcoal cache need to be trashed #define MSUM_DELETE_ALL (Handle)(-1) #define SEARCH_WINDOW (MailboxNodeHandle)(-1) // DeliveryStruct. Used to keep track of messages to be delivered to all opening IMAP mailboxes typedef struct DeliveryNode DeliveryNode, *DeliveryNodePtr, **DeliveryNodeHandle; struct DeliveryNode { TOCHandle toc; // toc to identify this deliverynode Boolean finished; // set to true once finished Boolean aborted; // set to true by the main thread to abort the download MailboxNodeHandle mailbox; // handle to the IMAP mailbox we're updating Handle ta; // stores list of summaries to be (a)dded Handle td; // stores list of summaries to be (d)eleted Handle tu; // stores list of summaries to be (u)pdated Handle tc; // stores list of summaries to be (c)opied IMAPSResultHandle results; // stores list of IMAP search results short threadCount; // number of threads adding results to this node Boolean filter; // set this flag if this mailbox needs to have filters run on it Boolean cleanupAttachments; // set this flag to true when updating a mailbox after a transfer so we go clean up attachments if we ought to. DeliveryNodeHandle next; }; // UpdateNode. Used to keep a list of windows waiting to be updated typedef struct UpdateNode UpdateNode, *UpdateNodePtr, **UpdateNodeHandle; struct UpdateNode { FSSpec mailboxSpec; // the mailbox this message lives in unsigned long uid; // uid of the message FSSpecHandle attachSpecs; // specs pointing to the attachments that have been downloaded UpdateNodeHandle next; }; // IMAPAppendStruct. Contains the information necessary to upload a POP message to an IMAP server typedef struct IMAPAppendStruct IMAPAppendStruct, *IMAPAppendPtr, **IMAPAppendHandle; struct IMAPAppendStruct { FSSpec spoolSpec; // the spooled message StateEnum fromState; // the state of the original message unsigned long fromFlags; // the flags from the original message Boolean transferred; // set to true when this message has been successfully transferred long serialNum; // the serial number of the original POP message FSSpec mailbox; // the POP mailbox this message came from }; // UIDCopyStruct. Contains source mailbox, old UID, and new UID. Used for main thread copys after a UIDPLUS response typedef struct UIDCopyStruct UIDCopyStruct, *UIDCopyPtr; struct UIDCopyStruct { FSSpec toSpec; // destination mailbox Handle hOldSums; // a copy of the summaries transferred. Handle hNewUIDs; // list of new UIDs from UIDPLUS response. Boolean copy; // true if this was a copy }; // global flag to turn off progress messages extern Boolean gFilteringUnderway; // macros to use for progress #define CAN_PROGRESS (!(gFilteringUnderway && !InAThread())) #define PROGRESS_START if (CAN_PROGRESS) OpenProgress() #define PROGRESS_MESSAGE(t,m) if (CAN_PROGRESS) ProgressMessage(t,m) #define PROGRESS_MESSAGER(t,r) if (CAN_PROGRESS) ProgressMessageR(t,r) #define PROGRESS_BAR(a,b,c,d,e) if (CAN_PROGRESS) Progress(a,b,c,d,e); #define BYTE_PROGRESS(a,b,c) if (CAN_PROGRESS) ByteProgress(a, b, c); #define PROGRESS_END if (CAN_PROGRESS) CloseProgress() // Note: if we're currently filtering, and the main thread makes a PROGRESS call, skip it. // Otherwise, we're a foreground non-filtering task, or a background task that can display progress. // resynch and related routines MailboxNodeHandle FetchNewMessages(TOCHandle tocH, Boolean fetchFlags, Boolean sameThread, Boolean filter, Boolean isAutoCheck); MailboxNodeHandle DoFetchNewMessages(FSSpecPtr mailboxSpec, Boolean fetchFlags, Boolean isAutoCheck); Boolean IMAPDelivery(TOCHandle inToc, Handle *toAdd, Handle *toUpdate, Handle *toDelete, Handle *toCopy, Boolean *filter, IMAPSResultHandle *results, MailboxNodeHandle *mbox, Boolean *checkAttachments); void IMAPAbortResync(TOCHandle toc); OSErr RsyncCurPersInbox(void); OSErr IMAPProcessMailboxes(FSSpecHandle mailboxes, TaskKindEnum task); Boolean DoIMAPProcessMailboxes(FSSpecHandle mailboxes, TaskKindEnum task); Boolean ResyncCurrentIMAPMailbox(void); Boolean UpdatableIMAPState(StateEnum state); OSErr SaveMinimalHeader(MAILSTREAM *stream); // Message downloading routines Boolean DoDownloadMessages(TOCHandle toc, Handle uids, Boolean attachmentsToo); OSErr UIDDownloadMessage(TOCHandle inToc, unsigned long uid, Boolean forceForeground, Boolean attachmentsToo); OSErr UIDDownloadMessages(TOCHandle inToc, Handle uids, Boolean forceForeground, Boolean attachmentsToo); Boolean IMAPMessagesWaiting(TOCHandle tocH, FSSpecPtr spoolSpec); void IMAPAbortMessageFetch(TOCHandle tocH, short sumNum); void IMAPRemoveCachedContents(TOCHandle tocH, short sumNum); void IMAPRemoveSelectedCachedContents(TOCHandle tocH); void IMAPFetchSelectedMessages(TOCHandle tocH, Boolean attach); OSErr IMAPTransferLocalCache(TOCHandle fromTocH, MSumPtr pOrigSum, TOCHandle toTocH, long newUid, Boolean copy); // mailbox polling void IMAPPoll(PersHandle pers); void IMAPPollMailboxes(MailboxNodeHandle tree); void IMAPPollMailboxTree(IMAPStreamPtr imapStream, MailboxNodeHandle tree, long numToPoll, long *remaining); // Attachment downloading routines Boolean IsIMAPAttachmentStub(FSSpecPtr spec); unsigned long DownloadIMAPAttachment(FSSpecPtr spec, MailboxNodeHandle mailbox, Boolean forceForeground); MailboxNodeHandle PETEHandleToMailboxNode(PETEHandle pte); unsigned long DoDownloadIMAPAttachments(FSSpecHandle attachments, MailboxNodeHandle mailbox); Boolean CanFetchAttachment(FSSpecPtr spec); void UpdateIMAPWindows(void); Boolean FetchAllIMAPAttachments(TOCHandle toc, short sumNum, Boolean forceForeground); Boolean FetchAllIMAPAttachmentsBySpec(FSSpecPtr spec, MailboxNodeHandle mailbox, Boolean forceForeground); Boolean HasStubFileAttachment(TOCHandle tocH, short sumNum); OSErr FetchIMAPAttachment(PETEHandle pte, FSSpecPtr spec, Boolean forceForeground); void RedisplayIMAPMessage(MyWindowPtr win); // functions to determine the state of a given message in an IMAP mailbox Boolean IMAPMessageDownloaded(TOCHandle t, short s); Boolean IMAPMessageBeingDownloaded(TOCHandle t, short s); // Message transfer OSErr IMAPTransferMessage(TOCHandle fromTocH, TOCHandle toTocH, unsigned long uid, Boolean copy, Boolean forceForeground); OSErr IMAPTransferMessages(TOCHandle fromTocH, TOCHandle toTocH, Handle uids, Boolean copy, Boolean forceForeground); OSErr DoTransferMessages(TOCHandle fromTocH, TOCHandle toTocH, Handle uids, Boolean copy); OSErr IMAPTransferMessagesToServer(TOCHandle fromTocH, TOCHandle toTocH, Handle sumNums, Boolean copy, Boolean forceForeground); OSErr IMAPTransferMessageToServer(TOCHandle tocH, TOCHandle toTocH, short sumNum, Boolean copy, Boolean forceForeground); OSErr DoTransferMessagesToServer(TOCHandle toTocH, IMAPAppendHandle spoolData, Boolean copy, Boolean forceForeground); void CleanUpAttachmentsAfterIMAPTransfer(TOCHandle tocH, short sumNum); char *FlagsString(char **flags, Boolean seen, Boolean deleted, Boolean flagged, Boolean answered, Boolean draft, Boolean recent, Boolean sent); void UpdatePOPMailboxes(void); OSErr IMAPTransferMessagesFromSearchWindow(TOCHandle fromTocH, TOCHandle toTocH, Boolean copy); OSErr IMAPMoveIMAPMessages(TOCHandle fromTocH, TOCHandle toTocH, Boolean copy); // Message deletion Boolean IMAPDeleteMessage(TOCHandle tocH, unsigned long uid, Boolean nuke, Boolean expunge, Boolean undelete); Boolean IMAPDeleteMessages(TOCHandle tocH, Handle uids, Boolean nuke, Boolean expunge, Boolean undelete,Boolean forceForeground); Boolean DoDeleteMessage(TOCHandle tocH, Handle uids, Boolean nuke, Boolean expunge, Boolean undelete); Boolean IMAPRemoveDeletedMessages(TOCHandle tocH); Boolean DoExpungeMailbox(TOCHandle tocH); Boolean DoExpungeMailboxLo(TOCHandle tocH, Boolean bCheckLocal); Boolean IMAPEmptyPersTrash(void); Boolean EmptyImapTrashes(IMAPEmptyTrashEnum which); Boolean IMAPMarkMessageAsDeleted(TOCHandle tocH, unsigned long uid, Boolean undelete); Boolean IMAPDeleteMessageDuringFiltering(TOCHandle tocH, PersHandle pers, unsigned long uid); Boolean IMAPDeleteMessagesFromSearchWindow(TOCHandle tocH); // offline commands OSErr PerformQueuedCommands(PersHandle pers, IMAPStreamPtr imapStream, Boolean progress); void ExecuteAllPendingIMAPCommands(void); OSErr QueueMessFlagChange(TOCHandle tocH, short sumNum, StateEnum state, Boolean bTrashed); Boolean PendingMessFlagChange(unsigned long uid, MailboxNodeHandle mbox); // some ordered UID list functions void UID_LL_OrderedInsert(UIDNodeHandle *head, UIDNodeHandle *item, Boolean isNew); void UID_LL_Zap(UIDNodeHandle *list); // Error reporting. OSErr IMAPError(short operation, short explanation, OSErr err); void IMAPAlert(IMAPStreamPtr stream, TaskKindEnum taskKind); void IMAPWarnings(void); void IMAPSpamWatchSupported(Boolean bSupported, Boolean bWarnIfNeeded); void IMAPResetSpamSupportPrefs(void); // Searching Boolean IMAPSearch(TOCHandle searchWin, BoxCountHandle boxesToSearch, IMAPSCHandle searchCriteria, Boolean matchAll); Boolean DoIMAPServerSearch(TOCHandle searchWin, BoxCountHandle specs, Handle specsToSeach, IMAPSCHandle searchCriteria, Boolean matchAll, long firstUID); void IMAPAbortSearch(TOCHandle searchWin); Boolean IMAPSearchMailbox(TOCHandle searchWin, BoxCountHandle boxesToSearch, MailboxNodeHandle boxToSearch, IMAPSCHandle searchCriteria, Boolean matchAlltocH, long firstUid); void UpdateIncrementalIMAPSearches(void); void IMAPProccessBoxesMainThread(Boolean bResync, Boolean bExpunge, Boolean bSearch); #define IMAPUpdateIncrementalSearches() IMAPProccessBoxesMainThread(false,false,true) // Filtering Boolean IMAPStartFiltering(TOCHandle tocToFilter, Boolean connect); void IMAPStartManualFiltering(void); Boolean IMAPTermMatch(MTPtr mt, MSumPtr sum); void IMAPStopFiltering(Boolean reallyDone); #define IMAPPostFilterResync() IMAPProccessBoxesMainThread(true,false,false) #define IMAPPostFilterExpunge() IMAPProccessBoxesMainThread(false,true,false) Boolean IMAPFilteringUnderway(void); void FlagForResync(TOCHandle tocH); void FlagForExpunge(TOCHandle tocH); void IMAPTocHBusy(TOCHandle tocH, Boolean busy); void ResyncOpenMailboxes(PersHandle pers); void ResetFilterFlags(TOCHandle tocH); Handle IMAPFetchMessageHeadersForFiltering(TOCHandle tocH, short sumNum); void GetNextWaitingIMAPToc(TOCHandle *toc); OSErr IMAPMoveMessageDuringFiltering(TOCHandle fromTocH, short sumNum, TOCHandle toTocH, Boolean copy, FilterPBPtr fpb); OSErr CacheIMAPMessageForSpamWatch(TOCHandle tocH, short sumNum); OSErr IMAPFilterProgress(TOCHandle tocH); OSErr DoIMAPFilterProgress(void); void IMAPFilteringCancelled(Boolean bOverride); // Miscellaneous utility functions DeliveryNodeHandle FindNodeByToc(TOCHandle toc); int pstrincmp(UPtr ps,CStr cs,short n); Boolean IsIMAPOperationUnderway(TaskKindEnum task); Boolean IsIMAPMailboxBusy(TOCHandle tocH); Boolean IMAPDoQuit(void); #ifdef DEBUG // Debugging void IMAPCollectFlags(void); #endif // Anthony Roybal's growing mailbox problem void MarkAsProcessed(FSSpec *spec); Boolean HasBeenProcessed(FSSpec *spec); #endif //IMAPDOWNLOAD_H