Back to index

lightning-sunbird  0.9+nobinonly
nsImapProtocol.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Lorenzo Colitti <lorenzo@colitti.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsImapProtocol_h___
00040 #define nsImapProtocol_h___
00041 
00042 #include "nsIImapProtocol.h"
00043 #include "nsIImapUrl.h"
00044 
00045 #include "nsMsgProtocol.h"
00046 #include "nsIEventQueue.h"
00047 #include "nsIStreamListener.h"
00048 #include "nsIOutputStream.h"
00049 #include "nsIOutputStream.h"
00050 #include "nsIInputStream.h"
00051 #include "nsImapCore.h"
00052 #include "nsString.h"
00053 #include "nsIProgressEventSink.h"
00054 #include "nsIInterfaceRequestor.h"
00055 #include "nsIInterfaceRequestorUtils.h"
00056 #include "nsISocketTransport.h"
00057 #include "nsIInputStreamPump.h"
00058 
00059 // imap event sinks
00060 #include "nsIImapMailFolderSink.h"
00061 #include "nsIImapServerSink.h"
00062 #include "nsIImapMessageSink.h"
00063 #include "nsIImapExtensionSink.h"
00064 #include "nsIImapMiscellaneousSink.h"
00065 
00066 #include "nsImapServerResponseParser.h"
00067 #include "nsImapProxyEvent.h"
00068 #include "nsImapFlagAndUidState.h"
00069 #include "nsIMAPNamespace.h"
00070 #include "nsVoidArray.h"
00071 #include "nsWeakPtr.h"
00072 #include "nsMsgLineBuffer.h" // we need this to use the nsMsgLineStreamBuffer helper class...
00073 #include "nsIInputStream.h"
00074 #include "nsIMsgIncomingServer.h"
00075 #include "nsISupportsArray.h"
00076 #include "nsIThread.h"
00077 #include "nsIRunnable.h"
00078 #include "nsIImapMockChannel.h"
00079 #include "nsILoadGroup.h"
00080 #include "nsCOMPtr.h"
00081 #include "nsIImapIncomingServer.h"
00082 #include "nsXPIDLString.h"
00083 #include "nsIMsgWindow.h"
00084 #include "nsIMsgLogonRedirector.h"
00085 #include "nsICacheListener.h"
00086 #include "nsIImapHeaderXferInfo.h"
00087 #include "nsMsgLineBuffer.h"
00088 #include "nsIAsyncInputStream.h"
00089 #include "nsITimer.h"
00090 class nsIMAPMessagePartIDArray;
00091 class nsIMsgIncomingServer;
00092 
00093 #define kDownLoadCacheSize 16000 // was 1536 - try making it bigger
00094 
00095 
00096 typedef struct _msg_line_info {
00097     const char   *adoptedMessageLine;
00098     PRUint32 uidOfMessage;
00099 } msg_line_info;
00100 
00101 
00102 class nsMsgImapLineDownloadCache : public nsIImapHeaderInfo, public nsByteArray
00103 {
00104 public:
00105   NS_DECL_ISUPPORTS
00106   NS_DECL_NSIIMAPHEADERINFO
00107   nsMsgImapLineDownloadCache();
00108   virtual ~nsMsgImapLineDownloadCache();
00109     PRUint32  CurrentUID();
00110     PRUint32  SpaceAvailable();
00111     PRBool CacheEmpty();
00112     
00113     msg_line_info *GetCurrentLineInfo();
00114     
00115 private:
00116     
00117     msg_line_info *fLineInfo;
00118     PRInt32 m_msgSize;
00119 };
00120 
00121 class nsMsgImapHdrXferInfo : public nsIImapHeaderXferInfo
00122 {
00123 public:
00124   NS_DECL_ISUPPORTS
00125   NS_DECL_NSIIMAPHEADERXFERINFO
00126   nsMsgImapHdrXferInfo();
00127   virtual ~nsMsgImapHdrXferInfo();
00128   // this will return null if we're full, in which case the client code
00129   // should transfer the headers and retry.
00130   nsresult GetFreeHeaderInfo(nsIImapHeaderInfo **aResult);
00131   void    ResetAll(); // reset HeaderInfo's for re-use
00132   void    ReleaseAll(); // release HeaderInfos (frees up memory)
00133   void    StartNewHdr(nsIImapHeaderInfo **newHdrInfo);
00134   // get the hdr info we're currently adding lines to
00135   nsIImapHeaderInfo           *GetCurrentHdrInfo();
00136   // call when we've finished adding lines to current hdr
00137   void    FinishCurrentHdr();
00138   nsCOMPtr <nsISupportsArray> m_hdrInfos;
00139   PRInt32   m_nextFreeHdrInfo;
00140 };
00141 
00142 // State Flags (Note, I use the word state in terms of storing 
00143 // state information about the connection (authentication, have we sent
00144 // commands, etc. I do not intend it to refer to protocol state)
00145 // Use these flags in conjunction with SetFlag/TestFlag/ClearFlag instead
00146 // of creating PRBools for everything....
00147 
00148 #define IMAP_RECEIVED_GREETING           0x00000001  /* should we pause for the next read */
00149 #define       IMAP_CONNECTION_IS_OPEN           0x00000004  /* is the connection currently open? */
00150 #define IMAP_WAITING_FOR_DATA         0x00000008
00151 #define IMAP_CLEAN_UP_URL_STATE       0x00000010 // processing clean up url state
00152 #define IMAP_ISSUED_LANGUAGE_REQUEST  0x00000020 // make sure we only issue the language request once per connection...
00153 
00154 class nsImapProtocol : public nsIImapProtocol, public nsIRunnable, public nsIInputStreamCallback,
00155  public nsSupportsWeakReference, public nsMsgProtocol
00156 {
00157 public:
00158   
00159   NS_DECL_ISUPPORTS
00160   NS_DECL_NSIINPUTSTREAMCALLBACK    
00161   nsImapProtocol();
00162   virtual ~nsImapProtocol();
00163   
00164   virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream, 
00165                                                                PRUint32 sourceOffset, PRUint32 length);
00166 
00167   // nsIRunnable method
00168   NS_IMETHOD Run();
00169   
00171   // we support the nsIImapProtocol interface
00173   NS_DECL_NSIIMAPPROTOCOL
00174 
00175   void CloseStreams();
00176 
00177   // message id string utilities.
00178   PRUint32           CountMessagesInIdString(const char *idString);
00179   static      PRBool HandlingMultipleMessages(const char *messageIdString);
00180   
00181   // escape slashes and double quotes in username/passwords for insecure login.
00182   static void EscapeUserNamePasswordString(const char *strToEscape, nsCString *resultStr);
00183   
00184   // used to start fetching a message.
00185   void GetShouldDownloadAllHeaders(PRBool *aResult);
00186   void GetArbitraryHeadersToDownload(char **aResult);
00187   virtual void AdjustChunkSize();
00188   virtual void FetchMessage(const char * messageIds, 
00189     nsIMAPeFetchFields whatToFetch,
00190     PRBool idAreUid,
00191     PRUint32 startByte = 0, PRUint32 endByte = 0,
00192     char *part = 0);
00193   void FetchTryChunking(const char * messageIds,
00194     nsIMAPeFetchFields whatToFetch,
00195     PRBool idIsUid,
00196     char *part,
00197     PRUint32 downloadSize,
00198     PRBool tryChunking);
00199   virtual void PipelinedFetchMessageParts(nsCString &uid, nsIMAPMessagePartIDArray *parts);
00200   void FallbackToFetchWholeMsg(const char *messageId, PRUint32 messageSize);
00201   
00202   // used when streaming a message fetch
00203   virtual nsresult BeginMessageDownLoad(PRUint32 totalSize, // for user, headers and body
00204     const char *contentType);     // some downloads are header only
00205   virtual void HandleMessageDownLoadLine(const char *line, PRBool isPartialLine, char *lineCopy=nsnull);
00206   virtual void NormalMessageEndDownload();
00207   virtual void AbortMessageDownLoad();
00208   virtual void PostLineDownLoadEvent(msg_line_info *downloadLineDontDelete);
00209   
00210   virtual void SetMailboxDiscoveryStatus(EMailboxDiscoverStatus status);
00211   virtual EMailboxDiscoverStatus GetMailboxDiscoveryStatus();
00212   
00213   virtual void ProcessMailboxUpdate(PRBool handlePossibleUndo);
00214   // Send log output...
00215   void Log(const char *logSubName, const char *extraInfo, const char *logData);
00216   static void LogImapUrl(const char *logMsg, nsIImapUrl *imapUrl);  
00217   // Comment from 4.5: We really need to break out the thread synchronizer from the
00218   // connection class...Not sure what this means
00219   PRBool  GetPseudoInterrupted();
00220   void PseudoInterrupt(PRBool the_interrupt);
00221   
00222   PRUint32 GetMessageSize(const char * messageId, PRBool idsAreUids);
00223   PRBool GetSubscribingNow();
00224   
00225   PRBool  DeathSignalReceived();
00226   void    ResetProgressInfo();
00227   void    SetActive(PRBool active);
00228   PRBool  GetActive();
00229   
00230   PRBool GetShowAttachmentsInline();
00231   
00232   // Sets whether or not the content referenced by the current ActiveEntry has been modified.
00233   // Used for MIME parts on demand.
00234   void    SetContentModified(IMAP_ContentModifiedType modified);
00235   PRBool  GetShouldFetchAllParts();
00236   PRBool  GetIgnoreExpunges() {return m_ignoreExpunges;}
00237   // Generic accessors required by the imap parser
00238   char * CreateNewLineFromSocket();
00239   PRInt32 GetConnectionStatus();
00240   void SetConnectionStatus(PRInt32 status);
00241   
00242   const char* GetImapHostName(); // return the host name from the url for the
00243   // current connection
00244   const char* GetImapUserName(); // return the user name from the identity;
00245   const char* GetImapServerKey(); // return the user name from the incoming server; 
00246   
00247   // state set by the imap parser...
00248   void NotifyMessageFlags(imapMessageFlagsType flags, nsMsgKey key);
00249   void NotifySearchHit(const char * hitLine);
00250   
00251   // Event handlers for the imap parser. 
00252   void DiscoverMailboxSpec(nsImapMailboxSpec * adoptedBoxSpec);
00253   void AlertUserEventUsingId(PRUint32 aMessageId);
00254   void AlertUserEvent(const char * message);
00255   void AlertUserEventFromServer(const char * aServerEvent);
00256   
00257   void ProgressEventFunctionUsingId(PRUint32 aMsgId);
00258   void ProgressEventFunctionUsingIdWithString(PRUint32 aMsgId, const char *
00259     aExtraInfo);
00260   void PercentProgressUpdateEvent(PRUnichar *message, PRInt32 currentProgress, PRInt32 maxProgress);
00261   void ShowProgress();
00262   
00263   // utility function calls made by the server
00264   
00265   void Copy(const char * messageList, const char *destinationMailbox, 
00266     PRBool idsAreUid);
00267   void Search(const char * searchCriteria,  PRBool useUID, 
00268     PRBool notifyHit = PR_TRUE);
00269   // imap commands issued by the parser
00270   void Store(const char * aMessageList, const char * aMessageData, PRBool
00271     aIdsAreUid);
00272   void ProcessStoreFlags(const char * messageIds,
00273     PRBool idsAreUids,
00274     imapMessageFlagsType flags,
00275     PRBool addFlags);
00276   void IssueUserDefinedMsgCommand(const char *command, const char * messageList);
00277   void FetchMsgAttribute(const char * messageIds, const char *attribute);
00278   void Expunge();
00279   void UidExpunge(const char* messageSet);
00280   void Close(PRBool shuttingDown = PR_FALSE, PRBool waitForResponse = PR_TRUE);
00281   void Check();
00282   void SelectMailbox(const char *mailboxName);
00283   // more imap commands
00284   void Logout(PRBool shuttingDown = PR_FALSE, PRBool waitForResponse = PR_TRUE);
00285   void Noop();
00286   void XServerInfo();
00287   void Netscape();
00288   void XMailboxInfo(const char *mailboxName);
00289   void XAOL_Option(const char *option);
00290   void MailboxData();
00291   void GetMyRightsForFolder(const char *mailboxName);
00292   void AutoSubscribeToMailboxIfNecessary(const char *mailboxName);
00293   void Bodystructure(const char *messageId, PRBool idIsUid);
00294   void PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePartIDArray *parts);
00295   
00296   
00297   // this function does not ref count!!! be careful!!!
00298   nsIImapUrl  *GetCurrentUrl() {return m_runningUrl;}
00299   
00300   // Tunnels
00301   virtual PRInt32 OpenTunnel (PRInt32 maxNumberOfBytesToRead);
00302   PRBool GetIOTunnellingEnabled();
00303   PRInt32 GetTunnellingThreshold();
00304   
00305   // acl and namespace stuff
00306   // notifies libmsg that we have a new personal/default namespace that we're using
00307   void CommitNamespacesForHostEvent();
00308   // notifies libmsg that we have new capability data for the current host
00309   void CommitCapability();
00310   
00311   // Adds a set of rights for a given user on a given mailbox on the current host.
00312   // if userName is NULL, it means "me," or MYRIGHTS.
00313   // rights is a single string of rights, as specified by RFC2086, the IMAP ACL extension.
00314   void AddFolderRightsForUser(const char *mailboxName, const char *userName, const char *rights);
00315   // Clears all rights for a given folder, for all users.
00316   void ClearAllFolderRights(const char *mailboxName, nsIMAPNamespace *nsForMailbox);
00317   void RefreshFolderACLView(const char *mailboxName, nsIMAPNamespace *nsForMailbox);
00318   
00319   nsresult SetFolderAdminUrl(const char *mailboxName);
00320   void HandleMemoryFailure();
00321   void HandleCurrentUrlError();
00322   
00323   // UIDPLUS extension
00324   void SetCopyResponseUid(const char* msgIdString);
00325   
00326   // Quota support
00327   void UpdateFolderQuotaData(nsCString& aQuotaRoot, PRUint32 aUsed, PRUint32 aMax);
00328   
00329 private:
00330   // the following flag is used to determine when a url is currently being run. It is cleared when we 
00331   // finish processng a url and it is set whenever we call Load on a url
00332   PRBool                        m_urlInProgress; 
00333   nsCOMPtr<nsIImapUrl>             m_runningUrl; // the nsIImapURL that is currently running
00334   nsImapAction       m_imapAction;  // current imap action associated with this connnection...
00335   
00336   nsCString             m_hostName;
00337   char                  *m_userName;
00338   char                  *m_serverKey;
00339   char                  *m_dataOutputBuf;
00340   nsMsgLineStreamBuffer * m_inputStreamBuffer;
00341   PRUint32              m_allocatedSize; // allocated size
00342   PRUint32        m_totalDataSize; // total data size
00343   PRUint32        m_curReadIndex;  // current read index
00344   nsCAutoString   m_trashFolderName;
00345   
00346   // Ouput stream for writing commands to the socket
00347   nsCOMPtr<nsISocketTransport>  m_transport; 
00348   
00349   nsCOMPtr<nsIInputStream>  m_channelInputStream;
00350   nsCOMPtr<nsIOutputStream> m_channelOutputStream;
00351   nsCOMPtr<nsIImapMockChannel>    m_mockChannel;   // this is the channel we should forward to people
00352   //nsCOMPtr<nsIRequest> mAsyncReadRequest; // we're going to cancel this when we're done with the conn.
00353   
00354   
00355   // ******* Thread support *******
00356   nsCOMPtr<nsIEventQueue> m_sinkEventQueue;
00357   nsCOMPtr<nsIThread>     m_iThread;
00358   PRThread     *m_thread;
00359   PRMonitor    *m_dataAvailableMonitor;   // used to notify the arrival of data from the server
00360   PRMonitor    *m_urlReadyToRunMonitor;   // used to notify the arrival of a new url to be processed
00361   PRMonitor    *m_pseudoInterruptMonitor;
00362   PRMonitor    *m_dataMemberMonitor;
00363   PRMonitor    *m_threadDeathMonitor;
00364   PRMonitor    *m_waitForBodyIdsMonitor;
00365   PRMonitor    *m_fetchMsgListMonitor;
00366   PRMonitor   *m_fetchBodyListMonitor;
00367   
00368   PRBool       m_imapThreadIsRunning;
00369   void ImapThreadMainLoop(void);
00370   PRInt32     m_connectionStatus;
00371   nsCString   m_connectionType;
00372 
00373   PRBool      m_nextUrlReadyToRun;
00374   nsWeakPtr   m_server;
00375   
00376   nsCOMPtr<nsIImapMailFolderSink>     m_imapMailFolderSink;
00377   nsCOMPtr<nsIImapMessageSink>           m_imapMessageSink;
00378   nsCOMPtr<nsIImapExtensionSink>      m_imapExtensionSink;
00379   nsCOMPtr<nsIImapMiscellaneousSink>  m_imapMiscellaneousSink;
00380   nsCOMPtr<nsIImapServerSink>         m_imapServerSink;
00381   
00382   // helper function to setup imap sink interface proxies
00383   void SetupSinkProxy();
00384   // End thread support stuff
00385   
00386   PRBool GetDeleteIsMoveToTrash();
00387   PRBool GetShowDeletedMessages();
00388   PRMonitor *GetDataMemberMonitor();
00389   nsCString m_currentCommand;
00390   nsImapServerResponseParser m_parser;
00391   nsImapServerResponseParser& GetServerStateParser() { return m_parser; };
00392   
00393   void HandleIdleResponses();
00394   virtual PRBool ProcessCurrentURL();
00395   void EstablishServerConnection();
00396   virtual void ParseIMAPandCheckForNewMail(const char* commandString =
00397     nsnull, PRBool ignoreBadNOResponses = PR_FALSE);
00398   // biff
00399   void PeriodicBiff();
00400   void SendSetBiffIndicatorEvent(nsMsgBiffState newState);
00401   PRBool      CheckNewMail();
00402   
00403   // folder opening and listing header functions
00404   void UpdatedMailboxSpec(nsImapMailboxSpec *aSpec);
00405   void FolderHeaderDump(PRUint32 *msgUids, PRUint32 msgCount);
00406   void FolderMsgDump(PRUint32 *msgUids, PRUint32 msgCount, nsIMAPeFetchFields fields);
00407   void FolderMsgDumpLoop(PRUint32 *msgUids, PRUint32 msgCount, nsIMAPeFetchFields fields);
00408   void WaitForPotentialListOfMsgsToFetch(PRUint32 **msgIdList, PRUint32 &msgCount);
00409   void WaitForPotentialListOfBodysToFetch(PRUint32 **msgIdList, PRUint32 &msgCount);
00410   void HeaderFetchCompleted();
00411   void UploadMessageFromFile(nsIFileSpec* fileSpec, const char* mailboxName, PRTime date,
00412     imapMessageFlagsType flags, nsCString &keywords);
00413   
00414   // mailbox name utilities.
00415   char *CreateEscapedMailboxName(const char *rawName);
00416   void SetupMessageFlagsString(nsCString & flagString,
00417     imapMessageFlagsType flags,
00418     PRUint16 userFlags);
00419   
00420   // header listing data
00421   PRBool    m_fetchMsgListIsNew;
00422   PRUint32  m_fetchCount;
00423   PRUint32  *m_fetchMsgIdList;
00424   PRBool    m_fetchBodyListIsNew;
00425   PRUint32  m_fetchBodyCount;
00426   PRUint32  *m_fetchBodyIdList;
00427   
00428   // initialization function given a new url and transport layer
00429   nsresult  SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer);
00430   void ReleaseUrlState(PRBool rerunningUrl); // release any state that is stored on a per action basis.
00431   
00433   // Communication methods --> Reading and writing protocol
00435   
00436   // SendData not only writes the NULL terminated data in dataBuffer to our output stream
00437   // but it also informs the consumer that the data has been written to the stream.
00438   // aSuppressLogging --> set to true if you wish to suppress logging for this particular command.
00439   // this is useful for making sure we don't log authenication information like the user's password (which was 
00440   // encoded anyway), but still we shouldn't add that information to the log.
00441   nsresult SendData(const char * dataBuffer, PRBool aSuppressLogging = PR_FALSE);
00442   
00443   // state ported over from 4.5
00444   PRBool  m_pseudoInterrupted;
00445   PRBool  m_active;
00446   PRBool  m_folderNeedsSubscribing;
00447   PRBool  m_folderNeedsACLRefreshed;
00448   PRBool  m_threadShouldDie;
00449   nsImapFlagAndUidState     *m_flagState;
00450   nsMsgBiffState        m_currentBiffState;
00451   // manage the IMAP server command tags
00452   char m_currentServerCommandTag[10];   // enough for a billion
00453   int  m_currentServerCommandTagNumber;
00454   void IncrementCommandTagNumber();
00455   char *GetServerCommandTag();  
00456   
00457   void StartTLS();
00458 
00459   // login related methods.
00460   nsresult GetPassword(nsXPIDLCString &password);
00461   // All of these methods actually issue protocol
00462   void Capability(); // query host for capabilities.
00463   void Language(); // set the language on the server if it supports it
00464   void Namespace();
00465   void InsecureLogin(const char *userName, const char *password);
00466   nsresult AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag);
00467   void ProcessAuthenticatedStateURL();
00468   void ProcessAfterAuthenticated();
00469   void ProcessSelectedStateURL();
00470   PRBool TryToLogon();
00471   
00472   // Process Authenticated State Url used to be one giant if statement. I've broken out a set of actions
00473   // based on the imap action passed into the url. The following functions are imap protocol handlers for
00474   // each action. They are called by ProcessAuthenticatedStateUrl.
00475   void OnLSubFolders();
00476   void OnAppendMsgFromFile();
00477 
00478   char *GetFolderPathString(); // OK to call from UI thread
00479 
00480   char * OnCreateServerSourceFolderPathString();
00481   char * OnCreateServerDestinationFolderPathString();
00482   nsresult CreateServerSourceFolderPathString(char **result);
00483   void OnCreateFolder(const char * aSourceMailbox);
00484   void OnEnsureExistsFolder(const char * aSourceMailbox);
00485   void OnSubscribe(const char * aSourceMailbox);
00486   void OnUnsubscribe(const char * aSourceMailbox);
00487   void RefreshACLForFolderIfNecessary(const char * mailboxName);
00488   void RefreshACLForFolder(const char * aSourceMailbox);
00489   void GetACLForFolder(const char *aMailboxName);
00490   void OnRefreshAllACLs();
00491   void OnListFolder(const char * aSourceMailbox, PRBool aBool);
00492   void OnStatusForFolder(const char * sourceMailbox);
00493   void OnDeleteFolder(const char * aSourceMailbox);
00494   void OnRenameFolder(const char * aSourceMailbox);
00495   void OnMoveFolderHierarchy(const char * aSourceMailbox);
00496   void DeleteFolderAndMsgs(const char * aSourceMailbox);
00497   void RemoveMsgsAndExpunge();
00498   void FindMailboxesIfNecessary();
00499   void CreateMailbox(const char *mailboxName);
00500   void DeleteMailbox(const char *mailboxName);
00501   void RenameMailbox(const char *existingName, const char *newName);
00502   PRBool CreateMailboxRespectingSubscriptions(const char *mailboxName);
00503   PRBool DeleteMailboxRespectingSubscriptions(const char *mailboxName);
00504   PRBool  RenameMailboxRespectingSubscriptions(const char *existingName, 
00505     const char *newName, 
00506     PRBool reallyRename);
00507   // notify the fe that a folder was deleted
00508   void FolderDeleted(const char *mailboxName);
00509   // notify the fe that a folder creation failed
00510   void FolderNotCreated(const char *mailboxName);
00511   // notify the fe that a folder was deleted
00512   void FolderRenamed(const char *oldName,
00513     const char *newName);
00514   
00515   PRBool FolderIsSelected(const char *mailboxName);
00516 
00517   PRBool      MailboxIsNoSelectMailbox(const char *mailboxName);
00518   char * CreatePossibleTrashName(const char *prefix);
00519   const char * GetTrashFolderName();
00520   PRBool FolderNeedsACLInitialized(const char *folderName);
00521   void DiscoverMailboxList();
00522   void DiscoverAllAndSubscribedBoxes();
00523   void MailboxDiscoveryFinished();
00524   void NthLevelChildList(const char *onlineMailboxPrefix, PRInt32 depth);
00525   void Lsub(const char *mailboxPattern, PRBool addDirectoryIfNecessary);
00526   void List(const char *mailboxPattern, PRBool addDirectoryIfNecessary);
00527   void Subscribe(const char *mailboxName);
00528   void Unsubscribe(const char *mailboxName);
00529   void Idle();
00530   void EndIdle(PRBool waitForResponse = PR_TRUE);
00531   // Some imap servers include the mailboxName following the dir-separator in the list of 
00532   // subfolders of the mailboxName. In fact, they are the same. So we should decide if
00533   // we should delete such subfolder and provide feedback if the delete operation succeed.
00534   PRBool DeleteSubFolders(const char* aMailboxName, PRBool & aDeleteSelf);
00535   PRBool  RenameHierarchyByHand(const char *oldParentMailboxName, 
00536     const char *newParentMailboxName);
00537   PRBool RetryUrl();
00538   
00539   nsresult GlobalInitialization();
00540   nsresult Configure(PRInt32 TooFastTime, PRInt32 IdealTime,
00541     PRInt32 ChunkAddSize, PRInt32 ChunkSize, PRInt32 ChunkThreshold,
00542     PRBool FetchByChunks, PRInt32 MaxChunkSize);
00543   nsresult GetMsgWindow(nsIMsgWindow ** aMsgWindow);
00544   // End Process AuthenticatedState Url helper methods
00545   
00546   // Quota support
00547   void GetQuotaDataIfSupported(const char *aBoxName);
00548   
00549   PRBool  m_trackingTime;
00550   PRTime  m_startTime;
00551   PRTime  m_endTime;
00552   PRTime  m_lastActiveTime;
00553   PRInt32 m_tooFastTime;
00554   PRInt32 m_idealTime;
00555   PRInt32 m_chunkAddSize;
00556   PRInt32 m_chunkStartSize;
00557   PRBool  m_fetchByChunks;
00558   PRBool  m_ignoreExpunges;
00559   PRBool  m_useSecAuth;
00560   PRInt32 m_socketType;
00561   PRInt32 m_chunkSize;
00562   PRInt32 m_chunkThreshold;
00563   nsMsgImapLineDownloadCache m_downloadLineCache;
00564   nsMsgImapHdrXferInfo  m_hdrDownloadCache;
00565   nsCOMPtr <nsIImapHeaderInfo> m_curHdrInfo;
00566   
00567   nsIImapHostSessionList * m_hostSessionList;
00568 
00569   PRBool m_fromHeaderSeen;
00570   
00571   // these settings allow clients to override various pieces of the connection info from the url
00572   PRBool m_overRideUrlConnectionInfo;
00573   
00574   nsCString m_logonHost;
00575   nsCString m_logonCookie;
00576   PRInt16 m_logonPort;
00577   
00578   nsXPIDLString mAcceptLanguages;
00579   
00580   // progress stuff
00581   void SetProgressString(PRInt32 stringId);
00582   
00583   nsXPIDLString m_progressString;
00584   PRInt32       m_progressStringId;
00585   PRInt32       m_progressIndex;
00586   PRInt32       m_progressCount;
00587   PRUint32      m_lastProgressStringId;
00588   PRInt32       m_lastPercent;
00589   PRInt64       m_lastProgressTime;                            
00590   
00591   PRBool m_notifySearchHit;
00592   PRBool m_checkForNewMailDownloadsHeaders;
00593   PRBool m_needNoop;
00594   PRBool m_idle;
00595   PRBool m_useIdle;
00596   PRInt32 m_noopCount;
00597   PRBool  m_autoSubscribe, m_autoUnsubscribe, m_autoSubscribeOnOpen;
00598   PRBool m_closeNeededBeforeSelect;
00599   PRBool m_retryUrlOnError;
00600 
00601   enum EMailboxHierarchyNameState {
00602     kNoOperationInProgress,
00603       kDiscoverBaseFolderInProgress,
00604       kDiscoverTrashFolderInProgress,
00605       kDeleteSubFoldersInProgress,
00606       kListingForInfoOnly,
00607       kListingForInfoAndDiscovery,
00608       kDiscoveringNamespacesOnly,
00609       kListingForCreate
00610   };
00611   EMailboxHierarchyNameState  m_hierarchyNameState;
00612   EMailboxDiscoverStatus      m_discoveryStatus;
00613   nsVoidArray                 m_listedMailboxList;
00614   nsVoidArray*                m_deletableChildren;
00615   PRUint32                    m_flagChangeCount;
00616   PRTime                      m_lastCheckTime;
00617   
00618   PRBool CheckNeeded();
00619 };
00620 
00621 // This small class is a "mock" channel because it is a mockery of the imap channel's implementation...
00622 // it's a light weight channel that we can return to necko when they ask for a channel on a url before
00623 // we actually have an imap protocol instance around which can run the url. Please see my comments in
00624 // nsIImapMockChannel.idl for more details..
00625 //
00626 // Threading concern: This class lives entirely in the UI thread.
00627 
00628 class nsICacheEntryDescriptor;
00629 
00630 class nsImapMockChannel : public nsIImapMockChannel
00631                         , public nsICacheListener
00632                         , public nsITransportEventSink
00633 {
00634 public:
00635 
00636   NS_DECL_ISUPPORTS
00637   NS_DECL_NSIIMAPMOCKCHANNEL
00638   NS_DECL_NSICHANNEL
00639   NS_DECL_NSIREQUEST
00640   NS_DECL_NSICACHELISTENER
00641   NS_DECL_NSITRANSPORTEVENTSINK
00642        
00643   nsImapMockChannel();
00644   virtual ~nsImapMockChannel();
00645   static nsresult Create (const nsIID& iid, void **result);
00646 
00647 protected:
00648   // we must break this circular reference between the imap url 
00649   // and the mock channel when we've finished running the url,
00650   // or we'll leak like crazy. The idea is that when nsImapUrl::RemoveChannel is called,
00651   // it will null out the url's pointer to the mock channel
00652   nsCOMPtr <nsIURI> m_url;
00653 
00654   nsCOMPtr<nsIURI> m_originalUrl;
00655   nsCOMPtr<nsILoadGroup> m_loadGroup;
00656   nsCOMPtr<nsIStreamListener> m_channelListener;
00657   // non owning ref of the context in order to fix a circular ref count
00658   // because the context is already the uri...
00659   nsISupports * m_channelContext;
00660   nsresult m_cancelStatus;
00661   nsLoadFlags mLoadFlags;
00662   nsCOMPtr<nsIProgressEventSink> mProgressEventSink;
00663   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
00664   nsCOMPtr<nsISupports> mOwner;
00665   nsCOMPtr<nsISupports> mSecurityInfo;
00666   nsCOMPtr<nsIRequest> mCacheRequest; // the request associated with a read from the cache
00667   nsCString m_ContentType;
00668   nsWeakPtr   m_protocol;
00669 
00670   PRBool mChannelClosed;
00671   PRBool mReadingFromCache;
00672   PRBool mTryingToReadPart;
00673   PRInt32 mContentLength;
00674 
00675   // cache related helper methods
00676   nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url
00677   PRBool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache....
00678   nsresult ReadFromImapConnection(); // creates a new imap connection to read the url 
00679   nsresult ReadFromMemCache(nsICacheEntryDescriptor *entry); // attempts to read the url out of our memory cache
00680   nsresult NotifyStartEndReadFromCache(PRBool start);
00681 
00682   // we end up daisy chaining multiple nsIStreamListeners into the load process. 
00683   nsresult SetupPartExtractorListener(nsIImapUrl * aUrl, nsIStreamListener * aConsumer);
00684 };
00685 
00686 #endif  // nsImapProtocol_h___