/* -*- 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 "nsIWeakReference.h" #include "nsIWeakReferenceUtils.h" #include "nsIMsgWindow.h" #include "nsImapMoveCoalescer.h" #include "nsAutoPtr.h" #include "nsStringGlue.h" #include "nsIMsgFilterList.h" #include "nsIMsgFilter.h" #include "nsIMsgFilterHitNotify.h" #include "nsIMsgFolderNotificationService.h" #include "nsTArray.h" class nsByteArray; class nsOutputFileStream; class nsIOFileStream; class nsInputFileStream; class nsIMsgFilter; class MSG_FolderInfoMail; class nsIMsgFilterList; 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(); void Init(uint64_t fileposition); virtual nsresult ParseFolderLine(const char *line, uint32_t lineLength); virtual 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); static bool IsEnvelopeLine(const char *buf, int32_t buf_size); nsCOMPtr m_newMsgHdr; /* current message header we're building */ nsCOMPtr m_mailDB; nsCOMPtr m_backupMailDB; nsMailboxParseState m_state; int64_t m_position; uint64_t m_envelope_pos; uint64_t m_headerstartpos; nsMsgKey m_new_key; // DB key for the new header. nsByteArray m_headers; nsByteArray m_envelope; 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 *GetNextHeaderInAggregate (nsTArray &list); void GetAggregateHeader (nsTArray &list, struct message_header *); void ClearAggregateHeader (nsTArray &list); struct message_header m_envelope_from; struct message_header m_envelope_date; 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; bool m_IgnoreXMozillaStatus; // 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(); bool IsRunningUrl() { return m_urlInProgress;} // returns true if we are currently running a url and false otherwise... NS_DECL_ISUPPORTS_INHERITED //////////////////////////////////////////////////////////////////////////////////////// // we suppport 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(nsIURI* aURL, 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); void FreeBuffers(); // data nsString m_folderName; nsCString m_inboxUri; nsByteArray m_inputStream; int32_t m_obuffer_size; char *m_obuffer; uint64_t m_graph_progress_total; uint64_t m_graph_progress_received; bool m_parsingDone; PRTime m_startTime; private: // the following flag is used to determine when a url is currently being run. It is cleared on calls // to ::StopBinding and it is set whenever we call Load on a url bool m_urlInProgress; nsWeakPtr m_folder; void ReleaseFolderLock(); nsresult AcquireFolderLock(); }; class nsParseNewMailState : public nsMsgMailboxParser , public nsIMsgFilterHitNotify { public: nsParseNewMailState(); NS_DECL_ISUPPORTS_INHERITED NS_IMETHOD FinishHeader() override; 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, uint32_t length, nsIMsgFolder *destFolder); virtual void ApplyFilters(bool *pMoved, nsIMsgWindow *msgWindow, uint64_t msgOffset); 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; uint32_t m_ibuffer_fp; char *m_ibuffer; uint32_t m_ibuffer_size; // used for applying move filters, because in the case of using a temporary // download file, the offset/key in the msg hdr is not right. uint64_t m_curHdrOffset; // 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