summaryrefslogtreecommitdiff
path: root/mailnews/local/src/nsParseMailbox.h
blob: 388f1e1b27cc88f6b17e69a72666e18ec03317f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsParseMailbox_H
#define nsParseMailbox_H

#include "mozilla/Attributes.h"
#include "nsIURI.h"
#include "nsIMsgParseMailMsgState.h"
#include "nsIStreamListener.h"
#include "nsMsgLineBuffer.h"
#include "nsIMsgDatabase.h"
#include "nsIMsgHdr.h"
#include "nsIMsgStatusFeedback.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsIDBChangeListener.h"
#include "nsIWeakReference.h"
#include "nsIWeakReferenceUtils.h"
#include "nsIMsgWindow.h"
#include "nsImapMoveCoalescer.h"
#include "nsAutoPtr.h"
#include "nsStringGlue.h"
#include "nsIMsgFilterList.h"
#include "nsIMsgFilter.h"
#include "nsIMsgFilterHitNotify.h"
#include "nsIMsgFolderNotificationService.h"
#include "nsTArray.h"

class nsByteArray;
class nsOutputFileStream;
class nsIOFileStream;
class nsInputFileStream;
class nsIMsgFilter;
class MSG_FolderInfoMail;
class nsIMsgFilterList;
class nsIMsgFolder;

/* Used for the various things that parse RFC822 headers...
 */
typedef struct message_header
{
  const char *value; /* The contents of a header (after ": ") */
  int32_t length;      /* The length of the data (it is not NULL-terminated.) */
} message_header;

// This object maintains the parse state for a single mail message.
class nsParseMailMessageState : public nsIMsgParseMailMsgState, public nsIDBChangeListener
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIMSGPARSEMAILMSGSTATE
  NS_DECL_NSIDBCHANGELISTENER

  nsParseMailMessageState();

  void                  Init(uint64_t fileposition);
  virtual nsresult      ParseFolderLine(const char *line, uint32_t lineLength);
  virtual nsresult      StartNewEnvelope(const char *line, uint32_t lineLength);
  nsresult              ParseHeaders();
  nsresult              FinalizeHeaders();
  nsresult              ParseEnvelope (const char *line, uint32_t line_size);
  nsresult              InternSubject (struct message_header *header);

  static bool    IsEnvelopeLine(const char *buf, int32_t buf_size);

  nsCOMPtr<nsIMsgDBHdr> m_newMsgHdr; /* current message header we're building */
  nsCOMPtr<nsIMsgDatabase>  m_mailDB;
  nsCOMPtr<nsIMsgDatabase> m_backupMailDB;

  nsMailboxParseState   m_state;
  int64_t              m_position;
  uint64_t              m_envelope_pos;
  uint64_t              m_headerstartpos;
  nsMsgKey              m_new_key;    // DB key for the new header.

  nsByteArray           m_headers;

  nsByteArray           m_envelope;

  struct message_header m_message_id;
  struct message_header m_references;
  struct message_header m_date;
  struct message_header m_delivery_date;
  struct message_header m_from;
  struct message_header m_sender;
  struct message_header m_newsgroups;
  struct message_header m_subject;
  struct message_header m_status;
  struct message_header m_mozstatus;
  struct message_header m_mozstatus2;
  struct message_header m_in_reply_to;
  struct message_header m_replyTo;
  struct message_header m_content_type;
  struct message_header m_bccList;

  // Support for having multiple To or Cc header lines in a message
  nsTArray<struct message_header*> m_toList;
  nsTArray<struct message_header*> m_ccList;
  struct message_header *GetNextHeaderInAggregate (nsTArray<struct message_header*> &list);
  void GetAggregateHeader (nsTArray<struct message_header*> &list, struct message_header *);
  void ClearAggregateHeader (nsTArray<struct message_header*> &list);

  struct message_header m_envelope_from;
  struct message_header m_envelope_date;
  struct message_header m_priority;
  struct message_header m_account_key;
  struct message_header m_keywords;
  // Mdn support
  struct message_header m_mdn_original_recipient;
  struct message_header m_return_path;
  struct message_header m_mdn_dnt; /* MDN Disposition-Notification-To: header */

  PRTime m_receivedTime;
  uint16_t              m_body_lines;

  bool                  m_IgnoreXMozillaStatus;

  // this enables extensions to add the values of particular headers to
  // the .msf file as properties of nsIMsgHdr. It is initialized from a
  // pref, mailnews.customDBHeaders
  nsTArray<nsCString>   m_customDBHeaders;
  struct message_header *m_customDBHeaderValues;
  nsCString m_receivedValue; // accumulated received header
protected:
  virtual ~nsParseMailMessageState();
};

// This class is part of the mailbox parsing state machine
class nsMsgMailboxParser : public nsIStreamListener, public nsParseMailMessageState, public nsMsgLineBuffer
{
public:
  nsMsgMailboxParser(nsIMsgFolder *);
  nsMsgMailboxParser();
  nsresult Init();

  bool    IsRunningUrl() { return m_urlInProgress;} // returns true if we are currently running a url and false otherwise...
  NS_DECL_ISUPPORTS_INHERITED

  ////////////////////////////////////////////////////////////////////////////////////////
  // we suppport the nsIStreamListener interface
  ////////////////////////////////////////////////////////////////////////////////////////
  NS_DECL_NSIREQUESTOBSERVER
  NS_DECL_NSISTREAMLISTENER

  void    SetDB (nsIMsgDatabase *mailDB) {m_mailDB = mailDB; }

  // message socket libnet callbacks, which come through folder pane
  nsresult ProcessMailboxInputStream(nsIURI* aURL, nsIInputStream *aIStream, uint32_t aLength);

  virtual void  DoneParsingFolder(nsresult status);
  virtual void  AbortNewHeader();

  // for nsMsgLineBuffer
  virtual nsresult HandleLine(const char *line, uint32_t line_length) override;

  void  UpdateDBFolderInfo();
  void  UpdateDBFolderInfo(nsIMsgDatabase *mailDB);
  void  UpdateStatusText(const char* stringName);

  // Update the progress bar based on what we know.
  virtual void    UpdateProgressPercent ();
  virtual void OnNewMessage(nsIMsgWindow *msgWindow);

protected:
  virtual ~nsMsgMailboxParser();
  nsCOMPtr<nsIMsgStatusFeedback> m_statusFeedback;

  virtual int32_t     PublishMsgHeader(nsIMsgWindow *msgWindow);
  void                FreeBuffers();

  // data
  nsString        m_folderName;
  nsCString       m_inboxUri;
  nsByteArray     m_inputStream;
  int32_t         m_obuffer_size;
  char            *m_obuffer;
  uint64_t        m_graph_progress_total;
  uint64_t        m_graph_progress_received;
  bool            m_parsingDone;
  PRTime          m_startTime;
private:
  // the following flag is used to determine when a url is currently being run. It is cleared on calls
  // to ::StopBinding and it is set whenever we call Load on a url
  bool      m_urlInProgress;
  nsWeakPtr m_folder;
  void ReleaseFolderLock();
  nsresult AcquireFolderLock();

};

class nsParseNewMailState : public nsMsgMailboxParser
, public nsIMsgFilterHitNotify
{
public:
  nsParseNewMailState();
  NS_DECL_ISUPPORTS_INHERITED

  NS_IMETHOD FinishHeader() override;

  nsresult Init(nsIMsgFolder *rootFolder, nsIMsgFolder *downloadFolder,
                nsIMsgWindow *aMsgWindow, nsIMsgDBHdr *aHdr,
                nsIOutputStream *aOutputStream);

  virtual void  DoneParsingFolder(nsresult status) override;

  void DisableFilters() {m_disableFilters = true;}

  NS_DECL_NSIMSGFILTERHITNOTIFY

  nsOutputFileStream *GetLogFile();
  virtual int32_t PublishMsgHeader(nsIMsgWindow *msgWindow) override;
  void            GetMsgWindow(nsIMsgWindow **aMsgWindow);
  nsresult EndMsgDownload();

  nsresult AppendMsgFromStream(nsIInputStream *fileStream, nsIMsgDBHdr *aHdr,
                               uint32_t length, nsIMsgFolder *destFolder);

  virtual void ApplyFilters(bool *pMoved, nsIMsgWindow *msgWindow,
                            uint64_t msgOffset);
  nsresult    ApplyForwardAndReplyFilter(nsIMsgWindow *msgWindow);
  virtual void OnNewMessage(nsIMsgWindow *msgWindow) override;

  // this keeps track of how many messages we downloaded that
  // aren't new - e.g., marked read, or moved to an other server.
  int32_t     m_numNotNewMessages;
protected:
  virtual ~nsParseNewMailState();
  virtual nsresult GetTrashFolder(nsIMsgFolder **pTrashFolder);
  virtual nsresult MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr,
                                          nsIMsgDatabase *sourceDB,
                                          nsIMsgFolder *destIFolder,
                                          nsIMsgFilter *filter,
                                          nsIMsgWindow *msgWindow);
  virtual void     MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr);
  virtual void     MarkFilteredMessageUnread(nsIMsgDBHdr *msgHdr);

  nsCOMPtr <nsIMsgFilterList> m_filterList;
  nsCOMPtr <nsIMsgFilterList> m_deferredToServerFilterList;
  nsCOMPtr <nsIMsgFolder> m_rootFolder;
  nsCOMPtr <nsIMsgWindow> m_msgWindow;
  nsCOMPtr <nsIMsgFolder> m_downloadFolder;
  nsCOMPtr<nsIOutputStream> m_outputStream;
  nsCOMArray <nsIMsgFolder> m_filterTargetFolders;

  RefPtr<nsImapMoveCoalescer> m_moveCoalescer;

  bool          m_msgMovedByFilter;
  bool          m_msgCopiedByFilter;
  bool          m_disableFilters;
  uint32_t      m_ibuffer_fp;
  char          *m_ibuffer;
  uint32_t      m_ibuffer_size;
  // used for applying move filters, because in the case of using a temporary
  // download file, the offset/key in the msg hdr is not right.
  uint64_t      m_curHdrOffset;

  // we have to apply the reply/forward filters in a second pass, after
  // msg quarantining and moving to other local folders, so we remember the
  // info we'll need to apply them with these vars.
  // these need to be arrays in case we have multiple reply/forward filters.
  nsTArray<nsCString> m_forwardTo;
  nsTArray<nsCString> m_replyTemplateUri;
  nsCOMPtr<nsIMsgDBHdr> m_msgToForwardOrReply;
  nsCOMPtr<nsIMsgFilter> m_filter;
  nsCOMPtr<nsIMsgRuleAction> m_ruleAction;
};

#endif