/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsParseMailbox_H #define nsParseMailbox_H #include "mozilla/Attributes.h" #include "nsIURI.h" #include "nsIMsgParseMailMsgState.h" #include "nsIStreamListener.h" #include "nsMsgLineBuffer.h" #include "nsIMsgDatabase.h" #include "nsIMsgHdr.h" #include "nsIMsgStatusFeedback.h" #include "nsCOMPtr.h" #include "nsCOMArray.h" #include "nsIDBChangeListener.h" #include "nsIWeakReferenceUtils.h" #include "nsIMsgWindow.h" #include "nsImapMoveCoalescer.h" #include "nsString.h" #include "nsIMsgFilterList.h" #include "nsIMsgFilter.h" #include "nsIMsgFilterHitNotify.h" #include "nsTArray.h" class nsOutputFileStream; class nsIMsgFolder; /* Used for the various things that parse RFC822 headers... */ typedef struct message_header { const char* value; /* The contents of a header (after ": ") */ int32_t length; /* The length of the data (it is not NULL-terminated.) */ } message_header; // This object maintains the parse state for a single mail message. class nsParseMailMessageState : public nsIMsgParseMailMsgState, public nsIDBChangeListener { public: NS_DECL_ISUPPORTS NS_DECL_NSIMSGPARSEMAILMSGSTATE NS_DECL_NSIDBCHANGELISTENER nsParseMailMessageState(); nsresult ParseFolderLine(const char* line, uint32_t lineLength); nsresult StartNewEnvelope(const char* line, uint32_t lineLength); nsresult ParseHeaders(); nsresult FinalizeHeaders(); nsresult ParseEnvelope(const char* line, uint32_t line_size); nsresult InternSubject(struct message_header* header); // Returns true if line looks like an mbox "From " line. static bool IsEnvelopeLine(const char* buf, int32_t buf_size); // Helpers for dealing with multi-value headers. struct message_header* GetNextHeaderInAggregate( nsTArray& list); void GetAggregateHeader(nsTArray& list, struct message_header*); void ClearAggregateHeader(nsTArray& list); nsCOMPtr m_newMsgHdr; /* current message header we're building */ nsCOMPtr m_mailDB; nsCOMPtr m_backupMailDB; nsMailboxParseState m_state; int64_t m_position; // The start of the "From " line (the line before the start of the message). uint64_t m_envelope_pos; // The start of the message headers (immediately follows "From " line). uint64_t m_headerstartpos; nsMsgKey m_new_key; // DB key for the new header. // The "From " line, if any. ::nsByteArray m_envelope; // These two point into the m_envelope buffer. struct message_header m_envelope_from; struct message_header m_envelope_date; // The raw header data. ::nsByteArray m_headers; // These all point into the m_headers buffer. struct message_header m_message_id; struct message_header m_references; struct message_header m_date; struct message_header m_delivery_date; struct message_header m_from; struct message_header m_sender; struct message_header m_newsgroups; struct message_header m_subject; struct message_header m_status; struct message_header m_mozstatus; struct message_header m_mozstatus2; struct message_header m_in_reply_to; struct message_header m_replyTo; struct message_header m_content_type; struct message_header m_bccList; // Support for having multiple To or Cc header lines in a message nsTArray m_toList; nsTArray m_ccList; struct message_header m_priority; struct message_header m_account_key; struct message_header m_keywords; // Mdn support struct message_header m_mdn_original_recipient; struct message_header m_return_path; struct message_header m_mdn_dnt; /* MDN Disposition-Notification-To: header */ PRTime m_receivedTime; uint16_t m_body_lines; uint16_t m_lastLineBlank; // this enables extensions to add the values of particular headers to // the .msf file as properties of nsIMsgHdr. It is initialized from a // pref, mailnews.customDBHeaders nsTArray m_customDBHeaders; struct message_header* m_customDBHeaderValues; nsCString m_receivedValue; // accumulated received header protected: virtual ~nsParseMailMessageState(); }; // This class is part of the mailbox parsing state machine class nsMsgMailboxParser : public nsIStreamListener, public nsParseMailMessageState, public nsMsgLineBuffer { public: explicit nsMsgMailboxParser(nsIMsgFolder*); nsMsgMailboxParser(); nsresult Init(); NS_DECL_ISUPPORTS_INHERITED //////////////////////////////////////////////////////////////////////////////////////// // we support the nsIStreamListener interface //////////////////////////////////////////////////////////////////////////////////////// NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER void SetDB(nsIMsgDatabase* mailDB) { m_mailDB = mailDB; } // message socket libnet callbacks, which come through folder pane nsresult ProcessMailboxInputStream(nsIInputStream* aIStream, uint32_t aLength); virtual void DoneParsingFolder(nsresult status); virtual void AbortNewHeader(); // for nsMsgLineBuffer virtual nsresult HandleLine(const char* line, uint32_t line_length) override; void UpdateDBFolderInfo(); void UpdateDBFolderInfo(nsIMsgDatabase* mailDB); void UpdateStatusText(const char* stringName); // Update the progress bar based on what we know. virtual void UpdateProgressPercent(); virtual void OnNewMessage(nsIMsgWindow* msgWindow); protected: virtual ~nsMsgMailboxParser(); nsCOMPtr m_statusFeedback; virtual int32_t PublishMsgHeader(nsIMsgWindow* msgWindow); // data nsString m_folderName; nsCString m_inboxUri; ::nsByteArray m_inputStream; uint64_t m_graph_progress_total; uint64_t m_graph_progress_received; private: nsWeakPtr m_folder; void ReleaseFolderLock(); nsresult AcquireFolderLock(); }; class nsParseNewMailState : public nsMsgMailboxParser, public nsIMsgFilterHitNotify { public: nsParseNewMailState(); NS_DECL_ISUPPORTS_INHERITED nsresult Init(nsIMsgFolder* rootFolder, nsIMsgFolder* downloadFolder, nsIMsgWindow* aMsgWindow, nsIMsgDBHdr* aHdr, nsIOutputStream* aOutputStream); virtual void DoneParsingFolder(nsresult status) override; void DisableFilters() { m_disableFilters = true; } NS_DECL_NSIMSGFILTERHITNOTIFY nsOutputFileStream* GetLogFile(); virtual int32_t PublishMsgHeader(nsIMsgWindow* msgWindow) override; void GetMsgWindow(nsIMsgWindow** aMsgWindow); nsresult EndMsgDownload(); nsresult AppendMsgFromStream(nsIInputStream* fileStream, nsIMsgDBHdr* aHdr, nsIMsgFolder* destFolder); void ApplyFilters(bool* pMoved, nsIMsgWindow* msgWindow); nsresult ApplyForwardAndReplyFilter(nsIMsgWindow* msgWindow); virtual void OnNewMessage(nsIMsgWindow* msgWindow) override; // this keeps track of how many messages we downloaded that // aren't new - e.g., marked read, or moved to an other server. int32_t m_numNotNewMessages; protected: virtual ~nsParseNewMailState(); virtual nsresult GetTrashFolder(nsIMsgFolder** pTrashFolder); virtual nsresult MoveIncorporatedMessage(nsIMsgDBHdr* mailHdr, nsIMsgDatabase* sourceDB, nsIMsgFolder* destIFolder, nsIMsgFilter* filter, nsIMsgWindow* msgWindow); virtual void MarkFilteredMessageRead(nsIMsgDBHdr* msgHdr); virtual void MarkFilteredMessageUnread(nsIMsgDBHdr* msgHdr); nsCOMPtr m_filterList; nsCOMPtr m_deferredToServerFilterList; nsCOMPtr m_rootFolder; nsCOMPtr m_msgWindow; nsCOMPtr m_downloadFolder; nsCOMPtr m_outputStream; nsCOMArray m_filterTargetFolders; RefPtr m_moveCoalescer; bool m_msgMovedByFilter; bool m_msgCopiedByFilter; bool m_disableFilters; // we have to apply the reply/forward filters in a second pass, after // msg quarantining and moving to other local folders, so we remember the // info we'll need to apply them with these vars. // these need to be arrays in case we have multiple reply/forward filters. nsTArray m_forwardTo; nsTArray m_replyTemplateUri; nsCOMPtr m_msgToForwardOrReply; nsCOMPtr m_filter; nsCOMPtr m_ruleAction; }; #endif