Back to index

lightning-sunbird  0.9+nobinonly
nsParseMailbox.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsParseMailbox_H
00039 #define nsParseMailbox_H
00040 
00041 #include "nsIURI.h"
00042 #include "nsIMsgParseMailMsgState.h"
00043 #include "nsMsgKeyArray.h"
00044 #include "nsVoidArray.h"
00045 #include "nsIStreamListener.h"
00046 #include "nsMsgLineBuffer.h"
00047 #include "nsIMsgHeaderParser.h"
00048 #include "nsIMsgDatabase.h"
00049 #include "nsIMsgHdr.h"
00050 #include "nsIMsgStatusFeedback.h"
00051 #include "nsXPIDLString.h"
00052 #include "nsLocalStringBundle.h"
00053 #include "nsCOMPtr.h"
00054 #include "nsCOMArray.h"
00055 #include "nsTime.h"
00056 #include "nsFileSpec.h"
00057 #include "nsIDBChangeListener.h"
00058 #include "nsIWeakReference.h"
00059 #include "nsIMsgWindow.h"
00060 #include "nsImapMoveCoalescer.h"
00061 
00062 #include "nsIMsgFilterList.h"
00063 #include "nsIMsgFilterHitNotify.h"
00064 #include "nsIMsgFolderNotificationService.h"
00065 
00066 class nsFileSpec;
00067 class nsByteArray;
00068 class nsOutputFileStream;
00069 class nsIOFileStream;
00070 class nsInputFileStream;
00071 class nsIMsgFilter;
00072 class MSG_FolderInfoMail;
00073 class nsIMsgFilterList;
00074 class nsIMsgFolder;
00075 
00076 /* Used for the various things that parse RFC822 headers...
00077  */
00078 typedef struct message_header
00079 {
00080   const char *value; /* The contents of a header (after ": ") */
00081   PRInt32 length;      /* The length of the data (it is not NULL-terminated.) */
00082 } message_header;
00083 
00084 // This object maintains the parse state for a single mail message.
00085 class nsParseMailMessageState : public nsIMsgParseMailMsgState
00086 {
00087 public:
00088   NS_DECL_ISUPPORTS
00089   NS_DECL_NSIMSGPARSEMAILMSGSTATE
00090        
00091   nsParseMailMessageState();
00092   virtual               ~nsParseMailMessageState();
00093   
00094   void                  Init(PRUint32 fileposition);
00095   virtual PRInt32       ParseFolderLine(const char *line, PRUint32 lineLength);
00096   virtual int           StartNewEnvelope(const char *line, PRUint32 lineLength);
00097   int                   ParseHeaders();
00098   int                   FinalizeHeaders();
00099   int                   ParseEnvelope (const char *line, PRUint32 line_size);
00100   int                   InternSubject (struct message_header *header);
00101   nsresult  InternRfc822 (struct message_header *header, char **ret_name);
00102   
00103   static PRBool      IsEnvelopeLine(const char *buf, PRInt32 buf_size);
00104   static int  msg_UnHex(char C); 
00105   
00106   nsCOMPtr<nsIMsgHeaderParser> m_HeaderAddressParser;
00107   
00108   nsCOMPtr<nsIMsgDBHdr> m_newMsgHdr; /* current message header we're building */
00109   nsCOMPtr<nsIMsgDatabase>  m_mailDB;
00110   
00111   nsMailboxParseState   m_state;
00112   PRUint32              m_position;
00113   PRUint32              m_envelope_pos;
00114   PRUint32              m_headerstartpos;
00115   
00116   nsByteArray           m_headers;
00117   
00118   nsByteArray           m_envelope;
00119   
00120   struct message_header m_message_id;
00121   struct message_header m_references;
00122   struct message_header m_date;
00123   struct message_header m_from;
00124   struct message_header m_sender;
00125   struct message_header m_newsgroups;
00126   struct message_header m_subject;
00127   struct message_header m_status;
00128   struct message_header m_mozstatus;
00129   struct message_header m_mozstatus2;
00130   struct message_header m_in_reply_to;
00131   struct message_header m_replyTo;
00132   struct message_header m_content_type;
00133   
00134   // Support for having multiple To or Cc header lines in a message
00135   nsVoidArray m_toList;
00136   nsVoidArray m_ccList;
00137   struct message_header *GetNextHeaderInAggregate (nsVoidArray &list);
00138   void GetAggregateHeader (nsVoidArray &list, struct message_header *);
00139   void ClearAggregateHeader (nsVoidArray &list);
00140   
00141   struct message_header m_envelope_from;
00142   struct message_header m_envelope_date;
00143   struct message_header m_priority;
00144   struct message_header m_account_key;
00145   struct message_header m_keywords;
00146   // Mdn support
00147   struct message_header m_mdn_original_recipient;
00148   struct message_header m_return_path;
00149   struct message_header m_mdn_dnt; /* MDN Disposition-Notification-To: header */
00150   
00151   PRTime m_receivedTime;
00152   PRUint16              m_body_lines;
00153   
00154   PRBool                m_IgnoreXMozillaStatus;
00155   PRBool                m_useReceivedDate;
00156   // this enables extensions to add the values of particular headers to 
00157   // the .msf file as properties of nsIMsgHdr. It is initialized from a
00158   // pref, mailnews.customDBHeaders
00159   nsCStringArray        m_customDBHeaders;
00160   struct message_header *m_customDBHeaderValues;
00161 protected:
00162   nsCOMPtr<nsIMsgStringService> mStringService;
00163 
00164 };
00165 
00166 // this should go in some utility class.
00167 inline int    nsParseMailMessageState::msg_UnHex(char C)
00168 {
00169        return ((C >= '0' && C <= '9') ? C - '0' :
00170               ((C >= 'A' && C <= 'F') ? C - 'A' + 10 :
00171                ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)));
00172 }
00173 
00174 // This class is part of the mailbox parsing state machine 
00175 class nsMsgMailboxParser : public nsIStreamListener, public nsParseMailMessageState, public nsMsgLineBuffer, public nsIDBChangeListener
00176 {
00177 public:
00178   nsMsgMailboxParser(nsIMsgFolder *);
00179   nsMsgMailboxParser();
00180   virtual ~nsMsgMailboxParser();
00181 
00182   PRBool  IsRunningUrl() { return m_urlInProgress;} // returns true if we are currently running a url and false otherwise...
00183   NS_DECL_ISUPPORTS_INHERITED
00184 
00186   // we suppport the nsIStreamListener interface 
00188   NS_DECL_NSIREQUESTOBSERVER
00189   NS_DECL_NSISTREAMLISTENER
00190   NS_DECL_NSIDBCHANGELISTENER
00191 
00192   void    SetDB (nsIMsgDatabase *mailDB) {m_mailDB = mailDB; }
00193 
00194   // message socket libnet callbacks, which come through folder pane
00195   virtual int ProcessMailboxInputStream(nsIURI* aURL, nsIInputStream *aIStream, PRUint32 aLength);
00196 
00197   virtual void       DoneParsingFolder(nsresult status);
00198   virtual void       AbortNewHeader();
00199 
00200   // for nsMsgLineBuffer
00201   virtual PRInt32 HandleLine(char *line, PRUint32 line_length);
00202 
00203   void  UpdateDBFolderInfo();
00204   void  UpdateDBFolderInfo(nsIMsgDatabase *mailDB);
00205   void  UpdateStatusText (PRUint32 stringID);
00206 
00207   // Update the progress bar based on what we know.
00208   virtual void    UpdateProgressPercent ();
00209 
00210 protected:
00211   nsCOMPtr<nsIMsgStatusFeedback> m_statusFeedback;
00212 
00213   virtual PRInt32     PublishMsgHeader(nsIMsgWindow *msgWindow);
00214   void                FreeBuffers();
00215 
00216   // data
00217   nsXPIDLString   m_folderName;
00218   nsXPIDLCString  m_inboxUri;
00219   nsByteArray     m_inputStream;
00220   PRInt32         m_obuffer_size;
00221   char            *m_obuffer;
00222   PRUint32        m_graph_progress_total;
00223   PRUint32        m_graph_progress_received;
00224   PRBool          m_parsingDone;
00225   nsTime          m_startTime;
00226 private:
00227   // the following flag is used to determine when a url is currently being run. It is cleared on calls
00228   // to ::StopBinding and it is set whenever we call Load on a url
00229   PRBool    m_urlInProgress;
00230   nsWeakPtr m_folder; 
00231   void Init();
00232   void ReleaseFolderLock();
00233 
00234 };
00235 
00236 class nsParseNewMailState : public nsMsgMailboxParser 
00237 , public nsIMsgFilterHitNotify
00238 {
00239 public:
00240   nsParseNewMailState();
00241   virtual ~nsParseNewMailState();
00242   NS_DECL_ISUPPORTS_INHERITED
00243   nsresult Init(nsIMsgFolder *rootFolder, nsIMsgFolder *downloadFolder, nsFileSpec &folder, 
00244                 nsIOFileStream *inboxFileStream, nsIMsgWindow *aMsgWindow,
00245                 PRBool downloadingToTempFile);
00246   
00247   virtual void       DoneParsingFolder(nsresult status);
00248   
00249   void DisableFilters() {m_disableFilters = PR_TRUE;}
00250   
00251   NS_DECL_NSIMSGFILTERHITNOTIFY
00252     
00253   nsOutputFileStream *GetLogFile();
00254   virtual PRInt32 PublishMsgHeader(nsIMsgWindow *msgWindow);
00255   void            GetMsgWindow(nsIMsgWindow **aMsgWindow);
00256   nsresult EndMsgDownload();
00257 
00258   nsresult AppendMsgFromFile(nsIOFileStream *fileStream, PRUint32 offset, 
00259                              PRUint32 length, nsFileSpec &destFileSpec);
00260 
00261   virtual void       ApplyFilters(PRBool *pMoved, nsIMsgWindow *msgWindow, 
00262                              PRUint32 msgOffset);
00263   nsresult    ApplyForwardAndReplyFilter(nsIMsgWindow *msgWindow);
00264   void        NotifyGlobalListeners(nsIMsgDBHdr *newHdr);
00265 
00266   // this keeps track of how many messages we downloaded that
00267   // aren't new - e.g., marked read, or moved to an other server.
00268   PRInt32     m_numNotNewMessages;
00269 protected:
00270   virtual nsresult GetTrashFolder(nsIMsgFolder **pTrashFolder);
00271   virtual nsresult  MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, 
00272                                           nsIMsgDatabase *sourceDB, 
00273                                           nsIMsgFolder *destIFolder,
00274                                           nsIMsgFilter *filter,
00275                                           nsIMsgWindow *msgWindow);
00276   virtual int   MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr);
00277   void          LogRuleHit(nsIMsgFilter *filter, nsIMsgDBHdr *msgHdr);
00278 
00279   nsCOMPtr <nsIMsgFilterList> m_filterList;
00280   nsCOMPtr <nsIMsgFilterList> m_deferredToServerFilterList;
00281   nsCOMPtr <nsIMsgFolder> m_rootFolder;
00282   nsCOMPtr <nsIMsgWindow> m_msgWindow;
00283   nsCOMPtr <nsIMsgFolder> m_downloadFolder;
00284   nsCOMArray <nsIMsgFolder> m_filterTargetFolders;
00285   nsCOMPtr <nsIMsgFolderNotificationService> m_notificationService;
00286 
00287   nsImapMoveCoalescer *m_moveCoalescer; // strictly owned by nsParseNewMailState;
00288 
00289   PRBool        m_msgMovedByFilter;
00290   nsIOFileStream  *m_inboxFileStream;
00291   nsFileSpec    m_inboxFileSpec;
00292   PRBool        m_disableFilters;
00293   PRBool        m_downloadingToTempFile;
00294   PRUint32      m_ibuffer_fp;
00295   char          *m_ibuffer;
00296   PRUint32      m_ibuffer_size;
00297   // used for applying move filters, because in the case of using a temporary
00298   // download file, the offset/key in the msg hdr is not right.
00299   PRUint32      m_curHdrOffset; 
00300 
00301   // we have to apply the reply/forward filters in a second pass, after 
00302   // msg quarantining and moving to other local folders, so we remember the 
00303   // info we'll need to apply them with these vars.
00304   // these need to be arrays in case we have multiple reply/forward filters.
00305   nsCStringArray     m_forwardTo;
00306   nsCStringArray     m_replyTemplateUri;
00307   nsCOMPtr <nsIMsgDBHdr> m_msgToForwardOrReply;
00308 };
00309 
00310 #endif