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