/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nsParseMailbox_H #define nsParseMailbox_H #include "nsIURI.h" #include "nsIMsgParseMailMsgState.h" #include "nsMsgKeyArray.h" #include "nsVoidArray.h" #include "nsIStreamListener.h" #include "nsMsgLineBuffer.h" #include "nsIMsgHeaderParser.h" #include "nsIMsgDatabase.h" #include "nsIMsgHdr.h" #include "nsIMsgStatusFeedback.h" #include "nsXPIDLString.h" #include "nsLocalStringBundle.h" #include "nsCOMPtr.h" #include "nsTime.h" #include "nsFileSpec.h" #include "nsIDBChangeListener.h" #include "nsIMsgFilterList.h" #include "nsIMsgFilterHitNotify.h" class nsFileSpec; class nsByteArray; class nsOutputFileStream; class nsIOFileStream; class nsInputFileStream; class nsIMsgFilter; class MSG_FolderInfoMail; class nsIMsgFilterList; class nsIFolder; /* Used for the various things that parse RFC822 headers... */ typedef struct message_header { const char *value; /* The contents of a header (after ": ") */ PRInt32 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: NS_DECL_ISUPPORTS NS_DECL_NSIMSGPARSEMAILMSGSTATE nsParseMailMessageState(); virtual ~nsParseMailMessageState(); void Init(PRUint32 fileposition); virtual PRInt32 ParseFolderLine(const char *line, PRUint32 lineLength); virtual int StartNewEnvelope(const char *line, PRUint32 lineLength); int ParseHeaders(); int FinalizeHeaders(); int ParseEnvelope (const char *line, PRUint32 line_size); int InternSubject (struct message_header *header); nsresult InternRfc822 (struct message_header *header, char **ret_name); static PRBool IsEnvelopeLine(const char *buf, PRInt32 buf_size); static int msg_UnHex(char C); nsCOMPtr m_HeaderAddressParser; nsCOMPtr m_newMsgHdr; /* current message header we're building */ nsCOMPtr m_mailDB; nsMailboxParseState m_state; PRUint32 m_position; PRUint32 m_envelope_pos; PRUint32 m_headerstartpos; 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_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_content_type; // Support for having multiple To or Cc header lines in a message nsVoidArray m_toList; nsVoidArray m_ccList; struct message_header *GetNextHeaderInAggregate (nsVoidArray &list); void GetAggregateHeader (nsVoidArray &list, struct message_header *); void ClearAggregateHeader (nsVoidArray &list); struct message_header m_envelope_from; struct message_header m_envelope_date; struct message_header m_priority; // 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 */ PRUint16 m_body_lines; PRBool m_IgnoreXMozillaStatus; protected: nsCOMPtr mStringService; }; // this should go in some utility class. inline int nsParseMailMessageState::msg_UnHex(char C) { return ((C >= '0' && C <= '9') ? C - '0' : ((C >= 'A' && C <= 'F') ? C - 'A' + 10 : ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0))); } // This class is part of the mailbox parsing state machine class nsMsgMailboxParser : public nsIStreamListener, public nsParseMailMessageState, public nsMsgLineBuffer, public nsMsgLineBufferHandler, public nsIDBChangeListener { public: nsMsgMailboxParser(); virtual ~nsMsgMailboxParser(); PRBool 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 NS_DECL_NSIDBCHANGELISTENER void SetDB (nsIMsgDatabase *mailDB) {m_mailDB = dont_QueryInterface(mailDB); } void SetIncrementalUpdate(PRBool update) {m_updateAsWeGo = update;} void SetIgnoreNonMailFolder(PRBool ignoreNonMailFolder) {m_ignoreNonMailFolder = ignoreNonMailFolder;} PRBool GetIsRealMailFolder() {return m_isRealMailFolder;} // message socket libnet callbacks, which come through folder pane virtual int ProcessMailboxInputStream(nsIURI* aURL, nsIInputStream *aIStream, PRUint32 aLength); virtual void DoneParsingFolder(nsresult status); virtual void AbortNewHeader(); // for nsMsgLineBuffer virtual PRInt32 HandleLine(char *line, PRUint32 line_length); void UpdateDBFolderInfo(); void UpdateDBFolderInfo(nsIMsgDatabase *mailDB); void UpdateStatusText (PRUint32 stringID); // Update the progress bar based on what we know. virtual void UpdateProgressPercent (); protected: nsCOMPtr m_statusFeedback; virtual PRInt32 PublishMsgHeader(nsIMsgWindow *msgWindow); virtual void FolderTypeSpecificTweakMsgHeader(nsIMsgDBHdr *tweakMe); void FreeBuffers(); // data nsString m_folderName; nsXPIDLCString m_inboxUri; nsByteArray m_inputStream; PRInt32 m_obuffer_size; char *m_obuffer; PRInt32 m_graph_progress_total; PRInt32 m_graph_progress_received; PRBool m_updateAsWeGo; PRBool m_parsingDone; PRBool m_ignoreNonMailFolder; PRBool m_isRealMailFolder; nsTime 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 PRBool m_urlInProgress; }; class nsParseNewMailState : public nsMsgMailboxParser , public nsIMsgFilterHitNotify { public: nsParseNewMailState(); virtual ~nsParseNewMailState(); NS_DECL_ISUPPORTS_INHERITED nsresult Init(nsIFolder *rootFolder, nsIMsgFolder *downloadFolder, nsFileSpec &folder, nsIOFileStream *inboxFileStream, nsIMsgWindow *aMsgWindow); virtual void DoneParsingFolder(nsresult status); virtual void SetUsingTempDB(PRBool usingTempDB, char *tmpDBName); void DisableFilters() {m_disableFilters = PR_TRUE;} #ifdef DOING_JSFILTERS // from jsmsg.cpp friend void JSMailFilter_MoveMessage(ParseNewMailState *state, nsIMsgDBHdr *msgHdr, nsMailDatabase *mailDB, const char *folder, nsIMsgFilter *filter, PRBool *pMoved); #endif // nsIMsgFilterHitNotification method(s) NS_IMETHOD ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindow *msgWindow, PRBool *applyMore); nsOutputFileStream *GetLogFile(); virtual PRInt32 PublishMsgHeader(nsIMsgWindow *msgWindow); protected: char *m_tmpdbName; // Temporary filename of new database PRBool m_usingTempDB; virtual void ApplyFilters(PRBool *pMoved, nsIMsgWindow *msgWindow); virtual nsresult GetTrashFolder(nsIMsgFolder **pTrashFolder); virtual nsresult MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, nsIMsgDatabase *sourceDB, const char *destFolder, nsIMsgFilter *filter, nsIMsgWindow *msgWindow); virtual int MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr); void LogRuleHit(nsIMsgFilter *filter, nsIMsgDBHdr *msgHdr); nsCOMPtr m_filterList; nsCOMPtr m_rootFolder; nsOutputFileStream *m_logFile; nsIOFileStream *m_inboxFileStream; nsFileSpec m_inboxFileSpec; PRBool m_disableFilters; PRBool m_msgMovedByFilter; PRUint32 m_ibuffer_fp; char *m_ibuffer; PRUint32 m_ibuffer_size; }; #ifdef IMAP_NEW_MAIL_HANDLED class ParseIMAPMailboxState : public ParseNewMailState { public: ParseIMAPMailboxState(MSG_IMAPHost *host, MSG_FolderInfoMail *folder, MSG_UrlQueue *urlQueue, TImapFlagAndUidState *flagStateAdopted); virtual ~ParseIMAPMailboxState(); // close the db virtual void DoneParsingFolder(nsresult status); virtual void SetPublishUID(PRInt32 uid); virtual void SetPublishByteLength(PRUint32 byteLength); virtual void SetNextSequenceNum(PRInt32 seqNum); const IDArray &GetBodyKeys() { return fFetchBodyKeys; } MSG_UrlQueue *GetFilterUrlQueue() {return fUrlQueue;} protected: virtual PRInt32 PublishMsgHeader(nsIMsgWindow *msgWindow); virtual void FolderTypeSpecificTweakMsgHeader(nsIMsgDBHdr *tweakMe); virtual void ApplyFilters(PRBool *pMoved, nsIMsgWindow *msgWindow); virtual MSG_FolderInfoMail *GetTrashFolder(); virtual nsresult MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, nsIMsgDatabase *sourceDB, char *destFolder, nsIMsgFilter *filter); virtual int MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr); private: PRBool fParsingInbox; PRBool fB2HaveWarnedUserOfOfflineFiltertarget; PRInt32 fNextMessagePublishUID; PRUint32 fNextMessageByteLength; MSG_UrlQueue *fUrlQueue; TImapFlagAndUidState *fFlagState; nsMsgKeyArray fFetchBodyKeys; PRInt32 fNextSequenceNum; MSG_FolderInfoContainer *m_imapContainer; MSG_IMAPHost *m_host; }; // If m_out_file is set, this parser will also write out the message, // adding a mozilla status line if one is not present. class ParseOutgoingMessage : public ParseMailMessageState { public: ParseOutgoingMessage(); virtual ~ParseOutgoingMessage(); void SetOutFile(XP_File out_file) {m_out_file = out_file;} XP_File GetOutFile() {return m_out_file;} void SetWriteMozillaStatus(PRBool writeMozStatus) {m_writeMozillaStatus = writeMozStatus;} virtual int StartNewEnvelope(const char *line, PRUint32 lineLength); virtual void FinishHeader(); virtual PRInt32 ParseFolderLine(const char *line, PRUint32 lineLength); virtual PRInt32 ParseBlock(const char *block, PRUint32 lineLength); virtual void Clear(); void AdvanceOutPosition(PRUint32 amountToAdvance); void SetWriteToOutFile(PRBool writeToOutFile) {m_writeToOutFile = writeToOutFile;} void FlushOutputBuffer(); PRUint32 m_bytes_written; protected: static PRInt32 LineBufferCallback(char *line, PRUint32 lineLength, void *closure); PRBool m_wroteXMozillaStatus; PRBool m_writeMozillaStatus; PRBool m_writeToOutFile; PRBool m_lastBodyLineEmpty; XP_File m_out_file; PRUint32 m_ouputBufferSize; char *m_outputBuffer; PRUint32 m_outputBufferIndex; }; #endif /* #ifdef NEW_MAIL_HANDLED */ #endif .