1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef nsImapMailFolder_h__
6 #define nsImapMailFolder_h__
7 
8 #include "mozilla/Attributes.h"
9 #include "nsImapCore.h"  // so that consumers including ImapMailFolder.h also get the kImapMsg* constants
10 #include "nsMsgDBFolder.h"
11 #include "nsIImapMailFolderSink.h"
12 #include "nsIImapMessageSink.h"
13 #include "nsICopyMessageListener.h"
14 #include "nsIUrlListener.h"
15 #include "nsIImapIncomingServer.h"  // we need this for its IID
16 #include "nsIMsgParseMailMsgState.h"
17 #include "nsImapUndoTxn.h"
18 #include "nsIMsgMessageService.h"
19 #include "nsIMsgFilterHitNotify.h"
20 #include "nsIMsgFilterList.h"
21 #include "prmon.h"
22 #include "nsIMsgImapMailFolder.h"
23 #include "nsIMsgThread.h"
24 #include "nsIImapMailFolderSink.h"
25 #include "nsIMsgFilterPlugin.h"
26 #include "nsISimpleEnumerator.h"
27 #include "nsIStringEnumerator.h"
28 #include "nsTHashMap.h"
29 #include "nsITimer.h"
30 #include "nsCOMArray.h"
31 #include "nsAutoSyncState.h"
32 
33 class nsImapMoveCoalescer;
34 class nsIMsgIdentity;
35 class nsIMsgOfflineImapOperation;
36 
37 #define COPY_BUFFER_SIZE 16384
38 
39 #define NS_IMAPMAILCOPYSTATE_IID                     \
40   {                                                  \
41     0xb64534f0, 0x3d53, 0x11d3, {                    \
42       0xac, 0x2a, 0x00, 0x80, 0x5f, 0x8a, 0xc9, 0x68 \
43     }                                                \
44   }
45 
46 class nsImapMailCopyState : public nsISupports {
47  public:
48   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMAPMAILCOPYSTATE_IID)
49 
50   NS_DECL_THREADSAFE_ISUPPORTS
51 
52   nsImapMailCopyState();
53 
54   nsCOMPtr<nsISupports> m_srcSupport;        // source file spec or folder
55   nsTArray<RefPtr<nsIMsgDBHdr>> m_messages;  // array of source messages
56   RefPtr<nsImapMoveCopyMsgTxn>
57       m_undoMsgTxn;  // undo object with this copy operation
58   nsCOMPtr<nsIMsgCopyServiceListener> m_listener;  // listener of this copy
59                                                    // operation
60   nsCOMPtr<nsIFile> m_tmpFile;         // temp file spec for copy operation
61   nsCOMPtr<nsIMsgWindow> m_msgWindow;  // msg window for copy operation
62 
63   nsCOMPtr<nsIMsgMessageService>
64       m_msgService;        // source folder message service; can
65                            // be Nntp, Mailbox, or Imap
66   bool m_isMove;           // is a move
67   bool m_selectedState;    // needs to be in selected state; append msg
68   bool m_isCrossServerOp;  // are we copying between imap servers?
69   uint32_t m_curIndex;     // message index to the message array which we are
70                            // copying
71   uint32_t m_unreadCount;  // num unread messages we're moving
72   bool m_streamCopy;
73   char* m_dataBuffer;  // temporary buffer for this copy operation
74   nsCOMPtr<nsIOutputStream> m_msgFileStream;  // temporary file (processed mail)
75   uint32_t m_dataBufferSize;
76   uint32_t m_leftOver;
77   bool m_allowUndo;
78   bool m_eatLF;
79   uint32_t m_newMsgFlags;      // only used if m_messages is empty
80   nsCString m_newMsgKeywords;  // ditto
81   // If the server supports UIDPLUS, this is the UID for the append,
82   // if we're doing an append.
83   nsMsgKey m_appendUID;
84 
85  private:
86   virtual ~nsImapMailCopyState();
87 };
88 
NS_DEFINE_STATIC_IID_ACCESSOR(nsImapMailCopyState,NS_IMAPMAILCOPYSTATE_IID)89 NS_DEFINE_STATIC_IID_ACCESSOR(nsImapMailCopyState, NS_IMAPMAILCOPYSTATE_IID)
90 
91 // ACLs for this folder.
92 // Generally, we will try to always query this class when performing
93 // an operation on the folder.
94 // If the server doesn't support ACLs, none of this data will be filled in.
95 // Therefore, we can assume that if we look up ourselves and don't find
96 // any info (and also look up "anyone") then we have full rights, that is, ACLs
97 // don't exist.
98 class nsImapMailFolder;
99 
100 // clang-format off
101 #define IMAP_ACL_READ_FLAG             0x0000001 // SELECT, CHECK, FETCH, PARTIAL, SEARCH, COPY from folder
102 #define IMAP_ACL_STORE_SEEN_FLAG       0x0000002 // STORE SEEN flag
103 #define IMAP_ACL_WRITE_FLAG            0x0000004 // STORE flags other than SEEN and DELETED
104 #define IMAP_ACL_INSERT_FLAG           0x0000008 // APPEND, COPY into folder
105 #define IMAP_ACL_POST_FLAG             0x0000010 // Can I send mail to the submission address for folder?
106 #define IMAP_ACL_CREATE_SUBFOLDER_FLAG 0x0000020 // Can I CREATE a subfolder of this folder?
107 #define IMAP_ACL_DELETE_FLAG           0x0000040 // STORE DELETED flag
108 #define IMAP_ACL_ADMINISTER_FLAG       0x0000080 // perform SETACL
109 #define IMAP_ACL_RETRIEVED_FLAG        0x0000100 // ACL info for this folder has been initialized
110 #define IMAP_ACL_EXPUNGE_FLAG          0x0000200 // can EXPUNGE or do implicit EXPUNGE on CLOSE
111 #define IMAP_ACL_DELETE_FOLDER         0x0000400 // can DELETE/RENAME folder
112 // clang-format on
113 
114 class nsMsgIMAPFolderACL {
115  public:
116   explicit nsMsgIMAPFolderACL(nsImapMailFolder* folder);
117   ~nsMsgIMAPFolderACL();
118 
119   bool SetFolderRightsForUser(const nsACString& userName,
120                               const nsACString& rights);
121 
122  public:
123   // generic for any user, although we might not use them in
124   // DO NOT use these for looking up information about the currently
125   // authenticated user. (There are some different checks and defaults we do).
126   // Instead, use the functions below, GetICan....()
127   // clang-format off
128   bool GetCanUserLookupFolder(const nsACString& userName);      // Is folder visible to LIST/LSUB?
129   bool GetCanUserReadFolder(const nsACString& userName);        // SELECT, CHECK, FETCH, PARTIAL, SEARCH, COPY from folder?
130   bool GetCanUserStoreSeenInFolder(const nsACString& userName); // STORE SEEN flag?
131   bool GetCanUserWriteFolder(const nsACString& userName);       // STORE flags other than SEEN and DELETED?
132   bool GetCanUserInsertInFolder(const nsACString& userName);    // APPEND, COPY into folder?
133   bool GetCanUserPostToFolder(const nsACString& userName);      // Can I send mail to the submission address for folder?
134   bool GetCanUserCreateSubfolder(const nsACString& userName);   // Can I CREATE a subfolder of this folder?
135   bool GetCanUserDeleteInFolder(const nsACString& userName);    // STORE DELETED flag, perform EXPUNGE?
136   bool GetCanUserAdministerFolder(const nsACString& userName);  // perform SETACL?
137 
138   // Functions to find out rights for the currently authenticated user.
139 
140   bool GetCanILookupFolder();      // Is folder visible to LIST/LSUB?
141   bool GetCanIReadFolder();        // SELECT, CHECK, FETCH, PARTIAL, SEARCH, COPY from folder?
142   bool GetCanIStoreSeenInFolder(); // STORE SEEN flag?
143   bool GetCanIWriteFolder();       // STORE flags other than SEEN and DELETED?
144   bool GetCanIInsertInFolder();    // APPEND, COPY into folder?
145   bool GetCanIPostToFolder();      // Can I send mail to the submission address for folder?
146   bool GetCanICreateSubfolder();   // Can I CREATE a subfolder of this folder?
147   bool GetCanIDeleteInFolder();    // STORE DELETED flag?
148   bool GetCanIAdministerFolder();  // perform SETACL?
149   bool GetCanIExpungeFolder();     // perform EXPUNGE?
150   // clang-format on
151 
152   bool GetDoIHaveFullRightsForFolder();  // Returns TRUE if I have full rights
153                                          // on this folder (all of the above
154                                          // return TRUE)
155 
156   bool GetIsFolderShared();  // We use this to see if the ACLs think a folder is
157                              // shared or not.
158   // We will define "Shared" in 5.0 to mean:
159   // At least one user other than the currently authenticated user has at least
160   // one explicitly-listed ACL right on that folder.
161 
162   // Returns a newly allocated string describing these rights
163   nsresult CreateACLRightsString(nsAString& rightsString);
164 
165   nsresult GetRightsStringForUser(const nsACString& userName,
166                                   nsCString& rights);
167 
168   nsresult GetOtherUsers(nsIUTF8StringEnumerator** aResult);
169 
170  protected:
171   bool GetFlagSetInRightsForUser(const nsACString& userName, char flag,
172                                  bool defaultIfNotFound);
173   void BuildInitialACLFromCache();
174   void UpdateACLCache();
175 
176  protected:
177   nsTHashMap<nsCStringHashKey, nsCString>
178       m_rightsHash;  // Hash table, mapping username strings to rights strings.
179   nsImapMailFolder* m_folder;
180   int32_t m_aclCount;
181 };
182 
183 /**
184  * Encapsulates parameters required to playback offline ops
185  * on given folder.
186  */
187 struct nsPlaybackRequest {
nsPlaybackRequestnsPlaybackRequest188   explicit nsPlaybackRequest(nsImapMailFolder* srcFolder,
189                              nsIMsgWindow* msgWindow)
190       : SrcFolder(srcFolder), MsgWindow(msgWindow) {}
191   nsImapMailFolder* SrcFolder;
192   nsCOMPtr<nsIMsgWindow> MsgWindow;
193 };
194 
195 class nsMsgQuota final : public nsIMsgQuota {
196  public:
197   NS_DECL_ISUPPORTS
198   NS_DECL_NSIMSGQUOTA
199 
200   nsMsgQuota(const nsACString& aName, const uint64_t& aUsage,
201              const uint64_t& aLimit);
202 
203  protected:
204   ~nsMsgQuota();
205 
206   nsCString mName;
207   uint64_t mUsage, mLimit;
208 };
209 
210 class nsImapMailFolder : public nsMsgDBFolder,
211                          public nsIMsgImapMailFolder,
212                          public nsIImapMailFolderSink,
213                          public nsIImapMessageSink,
214                          public nsICopyMessageListener,
215                          public nsIMsgFilterHitNotify {
216   static const uint32_t PLAYBACK_TIMER_INTERVAL_IN_MS = 500;
217 
218  public:
219   nsImapMailFolder();
220 
221   NS_DECL_ISUPPORTS_INHERITED
222 
223   // nsIMsgFolder methods:
224   NS_IMETHOD GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) override;
225 
226   NS_IMETHOD UpdateFolder(nsIMsgWindow* aWindow) override;
227 
228   NS_IMETHOD CreateSubfolder(const nsAString& folderName,
229                              nsIMsgWindow* msgWindow) override;
230   NS_IMETHOD AddSubfolder(const nsAString& aName,
231                           nsIMsgFolder** aChild) override;
232   NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener) override;
233 
234   NS_IMETHOD Compact(nsIUrlListener* aListener,
235                      nsIMsgWindow* aMsgWindow) override;
236   NS_IMETHOD CompactAll(nsIUrlListener* aListener, nsIMsgWindow* aMsgWindow,
237                         bool aCompactOfflineAlso) override;
238   NS_IMETHOD EmptyTrash(nsIMsgWindow* msgWindow,
239                         nsIUrlListener* aListener) override;
240   NS_IMETHOD CopyDataToOutputStreamForAppend(
241       nsIInputStream* aIStream, int32_t aLength,
242       nsIOutputStream* outputStream) override;
243   NS_IMETHOD CopyDataDone() override;
244   NS_IMETHOD DeleteStorage() override;
245   NS_IMETHOD Rename(const nsAString& newName, nsIMsgWindow* msgWindow) override;
246   NS_IMETHOD RenameSubFolders(nsIMsgWindow* msgWindow,
247                               nsIMsgFolder* oldFolder) override;
248   NS_IMETHOD GetNoSelect(bool* aResult) override;
249 
250   NS_IMETHOD GetPrettyName(nsAString& prettyName)
251       override;  // Override of the base, for top-level mail folder
252 
253   NS_IMETHOD GetFolderURL(nsACString& url) override;
254 
255   NS_IMETHOD UpdateSummaryTotals(bool force) override;
256 
257   NS_IMETHOD GetDeletable(bool* deletable) override;
258 
259   NS_IMETHOD GetSizeOnDisk(int64_t* size) override;
260 
261   NS_IMETHOD GetCanCreateSubfolders(bool* aResult) override;
262   NS_IMETHOD GetCanSubscribe(bool* aResult) override;
263 
264   NS_IMETHOD ApplyRetentionSettings() override;
265 
266   NS_IMETHOD AddMessageDispositionState(
267       nsIMsgDBHdr* aMessage, nsMsgDispositionState aDispositionFlag) override;
268   NS_IMETHOD MarkMessagesRead(const nsTArray<RefPtr<nsIMsgDBHdr>>& messages,
269                               bool markRead) override;
270   NS_IMETHOD MarkAllMessagesRead(nsIMsgWindow* aMsgWindow) override;
271   NS_IMETHOD MarkMessagesFlagged(const nsTArray<RefPtr<nsIMsgDBHdr>>& messages,
272                                  bool markFlagged) override;
273   NS_IMETHOD MarkThreadRead(nsIMsgThread* thread) override;
274   NS_IMETHOD SetLabelForMessages(const nsTArray<RefPtr<nsIMsgDBHdr>>& aMessages,
275                                  nsMsgLabelValue aLabel) override;
276   NS_IMETHOD SetJunkScoreForMessages(
277       const nsTArray<RefPtr<nsIMsgDBHdr>>& aMessages,
278       const nsACString& aJunkScore) override;
279   NS_IMETHOD DeleteSelf(nsIMsgWindow* msgWindow) override;
280   NS_IMETHOD ReadFromFolderCacheElem(
281       nsIMsgFolderCacheElement* element) override;
282   NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement* element) override;
283 
284   NS_IMETHOD GetDBFolderInfoAndDB(nsIDBFolderInfo** folderInfo,
285                                   nsIMsgDatabase** db) override;
286   MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD
287   DeleteMessages(nsTArray<RefPtr<nsIMsgDBHdr>> const& msgHeaders,
288                  nsIMsgWindow* msgWindow, bool deleteStorage, bool isMove,
289                  nsIMsgCopyServiceListener* listener, bool allowUndo) override;
290   NS_IMETHOD CopyMessages(nsIMsgFolder* srcFolder,
291                           nsTArray<RefPtr<nsIMsgDBHdr>> const& messages,
292                           bool isMove, nsIMsgWindow* msgWindow,
293                           nsIMsgCopyServiceListener* listener, bool isFolder,
294                           bool allowUndo) override;
295   NS_IMETHOD CopyFolder(nsIMsgFolder* srcFolder, bool isMove,
296                         nsIMsgWindow* msgWindow,
297                         nsIMsgCopyServiceListener* listener) override;
298   NS_IMETHOD CopyFileMessage(nsIFile* file, nsIMsgDBHdr* msgToReplace,
299                              bool isDraftOrTemplate, uint32_t aNewMsgFlags,
300                              const nsACString& aNewMsgKeywords,
301                              nsIMsgWindow* msgWindow,
302                              nsIMsgCopyServiceListener* listener) override;
303   NS_IMETHOD GetNewMessages(nsIMsgWindow* aWindow,
304                             nsIUrlListener* aListener) override;
305 
306   NS_IMETHOD GetFilePath(nsIFile** aPathName) override;
307   NS_IMETHOD SetFilePath(nsIFile* aPath) override;
308 
309   NS_IMETHOD Shutdown(bool shutdownChildren) override;
310 
311   NS_IMETHOD DownloadMessagesForOffline(
312       nsTArray<RefPtr<nsIMsgDBHdr>> const& messages,
313       nsIMsgWindow* msgWindow) override;
314 
315   NS_IMETHOD DownloadAllForOffline(nsIUrlListener* listener,
316                                    nsIMsgWindow* msgWindow) override;
317   NS_IMETHOD GetCanFileMessages(bool* aCanFileMessages) override;
318   NS_IMETHOD GetCanDeleteMessages(bool* aCanDeleteMessages) override;
319   NS_IMETHOD FetchMsgPreviewText(nsTArray<nsMsgKey> const& aKeysToFetch,
320                                  bool aLocalOnly, nsIUrlListener* aUrlListener,
321                                  bool* aAsyncResults) override;
322 
323   NS_IMETHOD AddKeywordsToMessages(
324       const nsTArray<RefPtr<nsIMsgDBHdr>>& aMessages,
325       const nsACString& aKeywords) override;
326   NS_IMETHOD RemoveKeywordsFromMessages(
327       const nsTArray<RefPtr<nsIMsgDBHdr>>& aMessages,
328       const nsACString& aKeywords) override;
329 
330   NS_IMETHOD NotifyCompactCompleted() override;
331 
332   // overrides nsMsgDBFolder::HasMsgOffline()
333   NS_IMETHOD HasMsgOffline(nsMsgKey msgKey, bool* _retval) override;
334   // overrides nsMsgDBFolder::GetOfflineFileStream()
335   NS_IMETHOD GetOfflineFileStream(nsMsgKey msgKey, int64_t* offset,
336                                   uint32_t* size,
337                                   nsIInputStream** aFileStream) override;
338 
339   NS_DECL_NSIMSGIMAPMAILFOLDER
340   NS_DECL_NSIIMAPMAILFOLDERSINK
341   NS_DECL_NSIIMAPMESSAGESINK
342   NS_DECL_NSICOPYMESSAGELISTENER
343 
344   // nsIUrlListener methods
345   NS_IMETHOD OnStartRunningUrl(nsIURI* aUrl) override;
346   MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD
347   OnStopRunningUrl(nsIURI* aUrl, nsresult aExitCode) override;
348 
349   NS_DECL_NSIMSGFILTERHITNOTIFY
350   NS_DECL_NSIJUNKMAILCLASSIFICATIONLISTENER
351 
352   NS_IMETHOD IsCommandEnabled(const nsACString& command, bool* result) override;
353   NS_IMETHOD SetFilterList(nsIMsgFilterList* aMsgFilterList) override;
354   NS_IMETHOD GetCustomIdentity(nsIMsgIdentity** aIdentity) override;
355 
356   /**
357    * This method is used to locate a folder where a msg could be present, not
358    * just the folder where the message first arrives, this method searches for
359    * the existence of msg in all the folders/labels that we retrieve from
360    * X-GM-LABELS also. overrides nsMsgDBFolder::GetOfflineMsgFolder()
361    *  @param msgKey key  of the msg for which we are trying to get the folder;
362    *  @param aMsgFolder  required folder;
363    */
364   NS_IMETHOD GetOfflineMsgFolder(nsMsgKey msgKey,
365                                  nsIMsgFolder** aMsgFolder) override;
366 
367   NS_IMETHOD GetIncomingServerType(nsACString& serverType) override;
368 
369   nsresult AddSubfolderWithPath(nsAString& name, nsIFile* dbPath,
370                                 nsIMsgFolder** child, bool brandNew = false);
371   nsresult MoveIncorporatedMessage(nsIMsgDBHdr* mailHdr,
372                                    nsIMsgDatabase* sourceDB,
373                                    const nsACString& destFolder,
374                                    nsIMsgFilter* filter,
375                                    nsIMsgWindow* msgWindow);
376 
377   // send notification to copy service listener.
378   nsresult OnCopyCompleted(nsISupports* srcSupport, nsresult exitCode);
379 
380   static nsresult AllocateUidStringFromKeys(const nsTArray<nsMsgKey>& keys,
381                                             nsCString& msgIds);
382   static nsresult BuildIdsAndKeyArray(
383       const nsTArray<RefPtr<nsIMsgDBHdr>>& messages, nsCString& msgIds,
384       nsTArray<nsMsgKey>& keyArray);
385 
386   // these might end up as an nsIImapMailFolder attribute.
387   nsresult SetSupportedUserFlags(uint32_t userFlags);
388   nsresult GetSupportedUserFlags(uint32_t* userFlags);
389 
390   // Find the start of a range of msgKeys that can hold srcCount headers.
391   nsresult FindOpenRange(nsMsgKey& fakeBase, uint32_t srcCount);
392 
393  protected:
394   virtual ~nsImapMailFolder();
395   // Helper methods
396 
397   virtual nsresult CreateChildFromURI(const nsACString& uri,
398                                       nsIMsgFolder** folder) override;
399   void FindKeysToAdd(const nsTArray<nsMsgKey>& existingKeys,
400                      nsTArray<nsMsgKey>& keysToFetch, uint32_t& numNewUnread,
401                      nsIImapFlagAndUidState* flagState);
402   void FindKeysToDelete(const nsTArray<nsMsgKey>& existingKeys,
403                         nsTArray<nsMsgKey>& keysToFetch,
404                         nsIImapFlagAndUidState* flagState, uint32_t boxFlags);
405   void PrepareToAddHeadersToMailDB(nsIImapProtocol* aProtocol);
406   void TweakHeaderFlags(nsIImapProtocol* aProtocol, nsIMsgDBHdr* tweakMe);
407 
408   nsresult SyncFlags(nsIImapFlagAndUidState* flagState);
409   nsresult HandleCustomFlags(nsMsgKey uidOfMessage, nsIMsgDBHdr* dbHdr,
410                              uint16_t userFlags, nsCString& keywords);
411   nsresult NotifyMessageFlagsFromHdr(nsIMsgDBHdr* dbHdr, nsMsgKey msgKey,
412                                      uint32_t flags);
413 
414   nsresult SetupHeaderParseStream(uint32_t size, const nsACString& content_type,
415                                   nsIMailboxSpec* boxSpec);
416   nsresult ParseAdoptedHeaderLine(const char* messageLine, nsMsgKey msgKey);
417   nsresult NormalEndHeaderParseStream(nsIImapProtocol* aProtocol,
418                                       nsIImapUrl* imapUrl);
419 
420   void EndOfflineDownload();
421 
422   /**
423    * At the end of a file-to-folder copy operation, copy the file to the
424    * offline store and/or add to the message database, (if needed).
425    *
426    * @param srcFile       file containing the message key
427    * @param msgKey        key to use for the new messages
428    */
429   nsresult CopyFileToOfflineStore(nsIFile* srcFile, nsMsgKey msgKey);
430 
431   nsresult MarkMessagesImapDeleted(nsTArray<nsMsgKey>* keyArray, bool deleted,
432                                    nsIMsgDatabase* db);
433 
434   // Notifies imap autosync that it should update this folder when it
435   // gets a chance.
436   void NotifyHasPendingMsgs();
437   void UpdatePendingCounts();
438   void SetIMAPDeletedFlag(nsIMsgDatabase* mailDB,
439                           const nsTArray<nsMsgKey>& msgids, bool markDeleted);
440   virtual bool ShowDeletedMessages();
441   virtual bool DeleteIsMoveToTrash();
442   nsresult GetFolder(const nsACString& name, nsIMsgFolder** pFolder);
443   nsresult GetTrashFolder(nsIMsgFolder** pTrashFolder);
444   bool TrashOrDescendentOfTrash(nsIMsgFolder* folder);
445   static bool ShouldCheckAllFolders(nsIImapIncomingServer* imapServer);
446   nsresult GetServerKey(nsACString& serverKey);
447   nsresult DisplayStatusMsg(nsIImapUrl* aImapUrl, const nsAString& msg);
448 
449   // nsresult RenameLocal(const char *newName);
450   nsresult AddDirectorySeparator(nsIFile* path);
451   nsresult CreateSubFolders(nsIFile* path);
452   nsresult GetDatabase() override;
453 
454   nsresult GetFolderOwnerUserName(nsACString& userName);
455   nsImapNamespace* GetNamespaceForFolder();
456   void SetNamespaceForFolder(nsImapNamespace* ns);
457 
458   nsMsgIMAPFolderACL* GetFolderACL();
459   nsresult CreateACLRightsStringForFolder(nsAString& rightsString);
460   nsresult GetBodysToDownload(nsTArray<nsMsgKey>* keysOfMessagesToDownload);
461   // Uber message copy service
462   nsresult CopyMessagesWithStream(nsIMsgFolder* srcFolder,
463                                   nsTArray<RefPtr<nsIMsgDBHdr>> const& messages,
464                                   bool isMove, bool isCrossServerOp,
465                                   nsIMsgWindow* msgWindow,
466                                   nsIMsgCopyServiceListener* listener,
467                                   bool allowUndo);
468   nsresult CopyStreamMessage(nsIMsgDBHdr* message, nsIMsgFolder* dstFolder,
469                              nsIMsgWindow* msgWindow, bool isMove);
470   nsresult InitCopyState(nsISupports* srcSupport,
471                          nsTArray<RefPtr<nsIMsgDBHdr>> const& messages,
472                          bool isMove, bool selectedState, bool acrossServers,
473                          uint32_t newMsgFlags, const nsACString& newMsgKeywords,
474                          nsIMsgCopyServiceListener* listener,
475                          nsIMsgWindow* msgWindow, bool allowUndo);
476   nsresult GetMoveCoalescer();
477   nsresult PlaybackCoalescedOperations();
478   virtual nsresult CreateBaseMessageURI(const nsACString& aURI) override;
479   // offline-ish methods
480   nsresult GetClearedOriginalOp(nsIMsgOfflineImapOperation* op,
481                                 nsIMsgOfflineImapOperation** originalOp,
482                                 nsIMsgDatabase** originalDB);
483   nsresult GetOriginalOp(nsIMsgOfflineImapOperation* op,
484                          nsIMsgOfflineImapOperation** originalOp,
485                          nsIMsgDatabase** originalDB);
486   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult CopyMessagesOffline(
487       nsIMsgFolder* srcFolder, nsTArray<RefPtr<nsIMsgDBHdr>> const& messages,
488       bool isMove, nsIMsgWindow* msgWindow,
489       nsIMsgCopyServiceListener* listener);
490   void SetPendingAttributes(const nsTArray<RefPtr<nsIMsgDBHdr>>& messages,
491                             bool aIsMove, bool aSetOffline);
492 
493   nsresult CopyOfflineMsgBody(nsIMsgFolder* srcFolder, nsIMsgDBHdr* destHdr,
494                               nsIMsgDBHdr* origHdr, nsIInputStream* inputStream,
495                               nsIOutputStream* outputStream);
496 
497   void GetTrashFolderName(nsAString& aFolderName);
498   bool ShowPreviewText();
499 
500   // Pseudo-Offline operation playback timer
501   static void PlaybackTimerCallback(nsITimer* aTimer, void* aClosure);
502 
503   nsresult CreatePlaybackTimer();
504 
505   // Allocate and initialize associated auto-sync state object.
506   void InitAutoSyncState();
507 
508   bool m_initialized;
509   bool m_haveDiscoveredAllFolders;
510   nsCOMPtr<nsIMsgParseMailMsgState> m_msgParser;
511   nsCOMPtr<nsIMsgFilterList> m_filterList;
512   nsCOMPtr<nsIMsgFilterPlugin> m_filterPlugin;  // XXX should be a list
513   // used with filter plugins to know when we've finished classifying and can
514   // playback moves
515   bool m_msgMovedByFilter;
516   RefPtr<nsImapMoveCoalescer>
517       m_moveCoalescer;  // strictly owned by the nsImapMailFolder
518   nsTArray<RefPtr<nsIMsgDBHdr>> m_junkMessagesToMarkAsRead;
519   /// list of keys to be moved to the junk folder
520   nsTArray<nsMsgKey> mSpamKeysToMove;
521   /// the junk destination folder
522   nsCOMPtr<nsIMsgFolder> mSpamFolder;
523   nsMsgKey m_curMsgUid;
524   uint32_t m_uidValidity;
525 
526   // These three vars are used to store counts from STATUS or SELECT command
527   // They include deleted messages, so they can differ from the generic
528   // folder total and unread counts.
529   int32_t m_numServerRecentMessages;
530   int32_t m_numServerUnseenMessages;
531   int32_t m_numServerTotalMessages;
532   // if server supports UIDNEXT, we store it here.
533   int32_t m_nextUID;
534 
535   int32_t m_nextMessageByteLength;
536   nsCOMPtr<nsIUrlListener> m_urlListener;
537   bool m_urlRunning;
538 
539   // undo move/copy transaction support
540   RefPtr<nsMsgTxn> m_pendingUndoTxn;
541   RefPtr<nsImapMailCopyState> m_copyState;
542   char m_hierarchyDelimiter;
543   int32_t m_boxFlags;
544   nsCString m_onlineFolderName;
545   nsCString m_ownerUserName;  // username of the "other user," as in
546   // "Other Users' Mailboxes"
547 
548   nsCString m_adminUrl;  // url to run to set admin privileges for this folder
549   nsImapNamespace* m_namespace;
550   bool m_verifiedAsOnlineFolder;
551   bool m_explicitlyVerify;  // whether or not we need to explicitly verify this
552                             // through LIST
553   bool m_folderIsNamespace;
554   bool m_folderNeedsSubscribing;
555   bool m_folderNeedsAdded;
556   bool m_folderNeedsACLListed;
557   bool m_performingBiff;
558   bool m_updatingFolder;
559   // These two vars are used to keep track of compaction state so we can know
560   // when to send a done notification.
561   bool m_compactingOfflineStore;
562   bool m_expunging;
563   bool m_applyIncomingFilters;  // apply filters to this folder, even if not the
564                                 // inbox
565   nsMsgIMAPFolderACL* m_folderACL;
566   uint32_t m_aclFlags;
567   uint32_t m_supportedUserFlags;
568 
569   // determines if we are on GMail server
570   bool m_isGmailServer;
571   // offline imap support
572   bool m_downloadingFolderForOfflineUse;
573   bool m_filterListRequiresBody;
574 
575   // auto-sync (automatic message download) support
576   RefPtr<nsAutoSyncState> m_autoSyncStateObj;
577 
578   // Quota support.
579   nsTArray<RefPtr<nsIMsgQuota>> m_folderQuota;
580   bool m_folderQuotaCommandIssued;
581   bool m_folderQuotaDataIsValid;
582 
583   // Pseudo-Offline Playback support
584   nsPlaybackRequest* m_pendingPlaybackReq;
585   nsCOMPtr<nsITimer> m_playbackTimer;
586   nsTArray<RefPtr<nsImapMoveCopyMsgTxn>> m_pendingOfflineMoves;
587   // hash table of mapping between messageids and message keys
588   // for pseudo hdrs.
589   nsTHashMap<nsCStringHashKey, nsMsgKey> m_pseudoHdrs;
590 
591   nsTArray<nsMsgKey> m_keysToFetch;
592   uint32_t m_totalKeysToFetch;
593 
594   /**
595    * delete if appropriate local storage for messages in this folder
596    *
597    * @parm aMessages array (of nsIMsgDBHdr) of messages to delete
598    *       (or an array of message keys)
599    * @parm aSrcFolder the folder containing the messages (optional)
600    */
601   void DeleteStoreMessages(const nsTArray<RefPtr<nsIMsgDBHdr>>& aMessages);
602   void DeleteStoreMessages(const nsTArray<nsMsgKey>& aMessages);
603   static void DeleteStoreMessages(const nsTArray<nsMsgKey>& aMessages,
604                                   nsIMsgFolder* aFolder);
605 };
606 #endif
607