Loading mailnews/local/src/nsParseMailbox.cpp +263 −239 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ nsMsgMailboxParser::nsMsgMailboxParser() : nsMsgLineBuffer(NULL, PR_FALSE) nsMsgMailboxParser::~nsMsgMailboxParser() { XP_FREE(m_mailboxName); PR_FREEIF(m_mailboxName); } void nsMsgMailboxParser::UpdateStatusText () Loading Loading @@ -1223,187 +1223,23 @@ int nsParseMailMessageState::FinalizeHeaders() #ifdef NEW_MAIL_HANDLED int ParseNewMailState::MarkFilteredMessageRead(nsMsgHdr *msgHdr) nsParseNewMailState::nsParseNewMailState(MSG_Master *master, nsFilePath &folder) { if (m_mailDB) m_mailDB->MarkHdrRead(msgHdr, TRUE, NULL); else msgHdr->OrFlags(kIsRead); return 0; } int ParseNewMailState::MoveIncorporatedMessage(nsMsgHdr *mailHdr, nsMailDatabase *sourceDB, char *destFolder, MSG_Filter *filter) { int err = 0; XP_File destFid; XP_File sourceFid = m_file; // SetMaster(master); m_mailboxName = PL_strdup(folder); // Make sure no one else is writing into this folder MSG_FolderInfo *lockedFolder = m_mailMaster->FindMailFolder (destFolder, FALSE /*create*/); if (lockedFolder && (err = lockedFolder->AcquireSemaphore (this)) != 0) return err; if (sourceFid == 0) { sourceFid = XP_FileOpen(m_mailboxName, xpMailFolder, XP_FILE_READ_BIN); } XP_ASSERT(sourceFid != 0); if (sourceFid == 0) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); return MK_MSG_FOLDER_UNREADABLE; // ### dmb } XP_FileSeek (sourceFid, mailHdr->GetMessageOffset(), SEEK_SET); int newMsgPos; destFid = XP_FileOpen(destFolder, xpMailFolder, XP_FILE_APPEND_BIN); if (!destFid) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } if (!XP_FileSeek (destFid, 0, SEEK_END)) { newMsgPos = ftell (destFid); } else { XP_ASSERT(FALSE); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (destFid); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } nsMailDatabase *mailDb = NULL; // don't force upgrade in place - open the db here before we start writing to the // destination file because XP_Stat can return file size including bytes written... MsgERR msgErr = nsMailDatabase::Open (destFolder, TRUE, &mailDb); PRUint32 length = mailHdr->GetByteLength(); m_ibuffer_size = 10240; m_ibuffer = NULL; while (!m_ibuffer && (m_ibuffer_size >= 512)) { m_ibuffer = (char *) XP_ALLOC(m_ibuffer_size); if (m_ibuffer == NULL) m_ibuffer_size /= 2; } XP_ASSERT(m_ibuffer != NULL); while ((length > 0) && m_ibuffer) { PRUint32 nRead = XP_FileRead (m_ibuffer, length > m_ibuffer_size ? m_ibuffer_size : length, sourceFid); if (nRead == 0) break; // we must monitor the number of bytes actually written to the file. (mscott) if (XP_FileWrite (m_ibuffer, nRead, destFid) != nRead) { XP_FileClose(sourceFid); XP_FileClose(destFid); // truncate destination file in case message was partially written XP_FileTruncate(destFolder,xpMailFolder,newMsgPos); if (lockedFolder) lockedFolder->ReleaseSemaphore(this); if (mailDb) mailDb->Close(); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; // caller (ApplyFilters) currently ignores error conditions } // the new mail parser isn't going to get the stream input, it seems, so we can't use // the OnStartBinding mechanism the mailbox parser uses. So, let's open the db right now. nsMailDatabase::Open(folder, PR_TRUE, &m_mailDB, PR_FALSE); length -= nRead; } XP_ASSERT(length == 0); // if we have made it this far then the message has successfully been written to the new folder // now add the header to the mailDb. if (eSUCCESS == msgErr) { nsMsgHdr *newHdr = new nsMsgHdr(); if (newHdr) { newHdr->CopyFromMsgHdr (mailHdr, sourceDB->GetDB(), mailDb->GetDB()); // set new byte offset, since the offset in the old file is certainly wrong newHdr->SetMessageKey (newMsgPos); newHdr->OrFlags(kNew); msgErr = mailDb->AddHdrToDB (newHdr, NULL, m_updateAsWeGo); } } else { if (mailDb) { mailDb->Close(); mailDb = NULL; } } XP_FileClose(sourceFid); XP_FileClose(destFid); int truncRet = XP_FileTruncate(m_mailboxName, xpMailFolder, mailHdr->GetMessageOffset()); XP_ASSERT(truncRet >= 0); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); // tell outgoing parser that we've truncated the Inbox m_parseMsgState->Init(mailHdr->GetMessageOffset()); MSG_FolderInfo *folder = m_mailMaster->FindMailFolder(destFolder, FALSE); if (folder) folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); if (mailDb != NULL) { // update the folder size so we won't reparse. UpdateDBFolderInfo(mailDb, destFolder); if (folder != NULL) folder->SummaryChanged(); mailDb->Close(); } // We are logging the hit with the old mailHdr, which should work, as long // as LogRuleHit doesn't assume the new hdr. if (m_filterList->IsLoggingEnabled()) LogRuleHit(filter, mailHdr); return err; } ParseNewMailState::ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail *folder) : nsMsgMailboxParser(folder->GetPathname()) { SetMaster(master); #ifdef DOING_FILTERS if (MSG_FilterList::Open(master, filterInbox, NULL, folder, &m_filterList) != FilterError_Success) m_filterList = NULL; m_logFile = NULL; #endif #ifdef DOING_MDN if (m_filterList) { const char *folderName = NULL; Loading @@ -1424,7 +1260,6 @@ ParseNewMailState::ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail XP_FREE(defaultFolderName); } } if (folderName) { MSG_Filter *newFilter = new MSG_Filter(filterInboxRule, "receipt"); Loading Loading @@ -1453,29 +1288,109 @@ ParseNewMailState::ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail } } } m_logFile = NULL; #endif DOING_MDN m_usingTempDB = FALSE; m_tmpdbName = NULL; m_disableFilters = FALSE; } ParseNewMailState::~ParseNewMailState() nsParseNewMailState::~nsParseNewMailState() { #ifdef DOING_FILTERS if (m_filterList != NULL) MSG_CancelFilterList(m_filterList); if (m_logFile != NULL) XP_FileClose(m_logFile); #endif if (m_mailDB) m_mailDB->Close(); if (m_usingTempDB) // if (m_usingTempDB) // { // XP_FileRemove(m_tmpdbName, xpMailFolderSummary); // } PR_FREEIF(m_tmpdbName); #ifdef DOING_FILTERS JSFilter_cleanup(); #endif } // This gets called for every message because libnet calls IncorporateBegin, // IncorporateWrite (once or more), and IncorporateComplete for every message. void nsParseNewMailState::DoneParsingFolder() { PRBool moved = FALSE; /* End of file. Flush out any partial line remaining in the buffer. */ if (m_ibuffer_fp > 0) { XP_FileRemove(m_tmpdbName, xpMailFolderSummary); ParseFolderLine(m_ibuffer, m_ibuffer_fp); m_ibuffer_fp = 0; } FREEIF(m_tmpdbName); JSFilter_cleanup(); PublishMsgHeader(); if (!moved && m_mailDB != NULL) // finished parsing, so flush db folder info UpdateDBFolderInfo(); #ifdef HAVE_FOLDERINFO if (m_folder != NULL) m_folder->SummaryChanged(); #endif /* We're done reading the folder - we don't need these things any more. */ PR_FREEIF (m_ibuffer); m_ibuffer_size = 0; PR_FREEIF (m_obuffer); m_obuffer_size = 0; } XP_File ParseNewMailState::GetLogFile () PRInt32 nsParseNewMailState::PublishMsgHeader() { PRBool moved = FALSE; FinishHeader(); if (m_newMsgHdr) { FolderTypeSpecificTweakMsgHeader(m_newMsgHdr); #ifdef DOING_FILTERS if (!m_disableFilters) { ApplyFilters(&moved); } #endif // DOING_FILTERS if (!moved) { if (m_mailDB) { PRUint32 newFlags; m_newMsgHdr->OrFlags(MSG_FLAG_NEW, &newFlags); // m_mailDB->AddHdrToDB (m_newMsgHdr, NULL, // m_updateAsWeGo); } #ifdef HAVE_FOLDERINFO if (m_folder) m_folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); #endif } // if it was moved by imap filter, m_parseMsgState->m_newMsgHdr == NULL else if (m_newMsgHdr) { m_newMsgHdr->Release(); } m_newMsgHdr = NULL; } return 0; } void nsParseNewMailState::SetUsingTempDB(PRBool usingTempDB, char *tmpDBName) { m_usingTempDB = usingTempDB; m_tmpdbName = tmpDBName; } #ifdef DOING_FILTERS XP_File nsParseNewMailState::GetLogFile () { // This log file is used by regular filters and JS filters if (m_logFile == NULL) Loading @@ -1483,7 +1398,7 @@ XP_File ParseNewMailState::GetLogFile () return m_logFile; } void ParseNewMailState::LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr) void nsParseNewMailState::LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr) { char *filterName = ""; time_t date; Loading Loading @@ -1524,14 +1439,14 @@ void ParseNewMailState::LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr) } } MSG_FolderInfoMail *ParseNewMailState::GetTrashFolder() MSG_FolderInfoMail *nsParseNewMailState::GetTrashFolder() { MSG_FolderInfo *foundTrash = NULL; GetMaster()->GetLocalMailFolderTree()->GetFoldersWithFlag(MSG_FOLDER_FLAG_TRASH, &foundTrash, 1); return foundTrash ? foundTrash->GetMailFolderInfo() : (MSG_FolderInfoMail *)NULL; } void ParseNewMailState::ApplyFilters(PRBool *pMoved) void nsParseNewMailState::ApplyFilters(PRBool *pMoved) { MSG_Filter *filter; PRInt32 filterCount = 0; Loading Loading @@ -1694,75 +1609,184 @@ void ParseNewMailState::ApplyFilters(PRBool *pMoved) *pMoved = msgMoved; } // This gets called for every message because libnet calls IncorporateBegin, // IncorporateWrite (once or more), and IncorporateComplete for every message. void ParseNewMailState::DoneParsingFolder() int nsParseNewMailState::MarkFilteredMessageRead(nsMsgHdr *msgHdr) { PRBool moved = FALSE; /* End of file. Flush out any partial line remaining in the buffer. */ if (m_ibuffer_fp > 0) if (m_mailDB) m_mailDB->MarkHdrRead(msgHdr, TRUE, NULL); else msgHdr->OrFlags(kIsRead); return 0; } int nsParseNewMailState::MoveIncorporatedMessage(nsMsgHdr *mailHdr, nsMailDatabase *sourceDB, char *destFolder, MSG_Filter *filter) { m_parseMsgState->ParseFolderLine(m_ibuffer, m_ibuffer_fp); m_ibuffer_fp = 0; int err = 0; XP_File destFid; XP_File sourceFid = m_file; // Make sure no one else is writing into this folder MSG_FolderInfo *lockedFolder = m_mailMaster->FindMailFolder (destFolder, FALSE /*create*/); if (lockedFolder && (err = lockedFolder->AcquireSemaphore (this)) != 0) return err; if (sourceFid == 0) { sourceFid = XP_FileOpen(m_mailboxName, xpMailFolder, XP_FILE_READ_BIN); } PublishMsgHeader(); if (!moved && m_mailDB != NULL) // finished parsing, so flush db folder info UpdateDBFolderInfo(); XP_ASSERT(sourceFid != 0); if (sourceFid == 0) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); if (m_folder != NULL) m_folder->SummaryChanged(); return MK_MSG_FOLDER_UNREADABLE; // ### dmb } /* We're done reading the folder - we don't need these things any more. */ FREEIF (m_ibuffer); m_ibuffer_size = 0; FREEIF (m_obuffer); m_obuffer_size = 0; XP_FileSeek (sourceFid, mailHdr->GetMessageOffset(), SEEK_SET); int newMsgPos; destFid = XP_FileOpen(destFolder, xpMailFolder, XP_FILE_APPEND_BIN); if (!destFid) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } PRInt32 ParseNewMailState::PublishMsgHeader() if (!XP_FileSeek (destFid, 0, SEEK_END)) { PRBool moved = FALSE; newMsgPos = ftell (destFid); } else { XP_ASSERT(FALSE); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (destFid); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } m_parseMsgState->FinishHeader(); nsMailDatabase *mailDb = NULL; // don't force upgrade in place - open the db here before we start writing to the // destination file because XP_Stat can return file size including bytes written... MsgERR msgErr = nsMailDatabase::Open (destFolder, TRUE, &mailDb); PRUint32 length = mailHdr->GetByteLength(); if (m_parseMsgState->m_newMsgHdr) m_ibuffer_size = 10240; m_ibuffer = NULL; while (!m_ibuffer && (m_ibuffer_size >= 512)) { FolderTypeSpecificTweakMsgHeader(m_parseMsgState->m_newMsgHdr); if (!m_disableFilters) { ApplyFilters(&moved); m_ibuffer = (char *) XP_ALLOC(m_ibuffer_size); if (m_ibuffer == NULL) m_ibuffer_size /= 2; } if (!moved) XP_ASSERT(m_ibuffer != NULL); while ((length > 0) && m_ibuffer) { if (m_mailDB) PRUint32 nRead = XP_FileRead (m_ibuffer, length > m_ibuffer_size ? m_ibuffer_size : length, sourceFid); if (nRead == 0) break; // we must monitor the number of bytes actually written to the file. (mscott) if (XP_FileWrite (m_ibuffer, nRead, destFid) != nRead) { m_parseMsgState->m_newMsgHdr->OrFlags(kNew); m_mailDB->AddHdrToDB (m_parseMsgState->m_newMsgHdr, NULL, m_updateAsWeGo); XP_FileClose(sourceFid); XP_FileClose(destFid); // truncate destination file in case message was partially written XP_FileTruncate(destFolder,xpMailFolder,newMsgPos); if (lockedFolder) lockedFolder->ReleaseSemaphore(this); if (mailDb) mailDb->Close(); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; // caller (ApplyFilters) currently ignores error conditions } if (m_folder) m_folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); length -= nRead; } } // if it was moved by imap filter, m_parseMsgState->m_newMsgHdr == NULL else if (m_parseMsgState->m_newMsgHdr) XP_ASSERT(length == 0); // if we have made it this far then the message has successfully been written to the new folder // now add the header to the mailDb. if (eSUCCESS == msgErr) { m_parseMsgState->m_newMsgHdr->unrefer(); nsMsgHdr *newHdr = new nsMsgHdr(); if (newHdr) { newHdr->CopyFromMsgHdr (mailHdr, sourceDB->GetDB(), mailDb->GetDB()); // set new byte offset, since the offset in the old file is certainly wrong newHdr->SetMessageKey (newMsgPos); newHdr->OrFlags(kNew); msgErr = mailDb->AddHdrToDB (newHdr, NULL, m_updateAsWeGo); } m_parseMsgState->m_newMsgHdr = NULL; } return 0; else { if (mailDb) { mailDb->Close(); mailDb = NULL; } } void ParseNewMailState::SetUsingTempDB(PRBool usingTempDB, char *tmpDBName) XP_FileClose(sourceFid); XP_FileClose(destFid); int truncRet = XP_FileTruncate(m_mailboxName, xpMailFolder, mailHdr->GetMessageOffset()); XP_ASSERT(truncRet >= 0); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); // tell outgoing parser that we've truncated the Inbox m_parseMsgState->Init(mailHdr->GetMessageOffset()); MSG_FolderInfo *folder = m_mailMaster->FindMailFolder(destFolder, FALSE); if (folder) folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); if (mailDb != NULL) { m_usingTempDB = usingTempDB; m_tmpdbName = tmpDBName; // update the folder size so we won't reparse. UpdateDBFolderInfo(mailDb, destFolder); if (folder != NULL) folder->SummaryChanged(); mailDb->Close(); } // We are logging the hit with the old mailHdr, which should work, as long // as LogRuleHit doesn't assume the new hdr. if (m_filterList->IsLoggingEnabled()) LogRuleHit(filter, mailHdr); return err; } #endif // DOING_FILTERS #ifdef IMAP_NEW_MAIL_HANDLED ParseIMAPMailboxState::ParseIMAPMailboxState(MSG_Master *master, MSG_IMAPHost *host, MSG_FolderInfoMail *folder, MSG_UrlQueue *urlQueue, TImapFlagAndUidState *flagStateAdopted) : ParseNewMailState(master, folder), fUrlQueue(urlQueue) : nsParseNewMailState(master, folder), fUrlQueue(urlQueue) { MSG_FolderInfoContainer *imapContainer = m_mailMaster->GetImapMailFolderTreeForHost(host->GetHostName()); MSG_FolderInfo *filteredFolder = imapContainer->FindMailPathname(folder->GetPathname()); Loading Loading @@ -1910,7 +1934,7 @@ MSG_FolderInfoMail *ParseIMAPMailboxState::GetTrashFolder() void ParseIMAPMailboxState::ApplyFilters(PRBool *pMoved) { if (fParsingInbox && !(GetCurrentMsg()->GetFlags() & kIsRead) ) ParseNewMailState::ApplyFilters(pMoved); nsParseNewMailState::ApplyFilters(pMoved); else *pMoved = FALSE; Loading Loading @@ -2184,4 +2208,4 @@ void ParseOutgoingMessage::FlushOutputBuffer() } } #endif /* NEW_MAIL_HANDLED */ #endif /* IMAP_NEW_MAIL_HANDLED */ mailnews/local/src/nsParseMailbox.h +24 −28 Original line number Diff line number Diff line Loading @@ -26,24 +26,23 @@ #include "nsMsgLineBuffer.h" #include "nsMsgRFC822Parser.h" class nsFilePath; class nsByteArray; class nsMailDatabase; class nsMsgHdr; class nsOutputFileStream; class nsInputFileStream; class MSG_Filter; class MSG_Master; class MSG_FolderInfoMail; class MSG_FilterList; /* class MSG_Master; class MailDB; class MSG_Pane; class MSG_FolderPane; class MailMessageHdr; struct MSG_FilterList; struct MSG_Filter; struct MSG_Rule; class MailMessageHdr; class MSG_UrlQueue; class TImapFlagAndUidState; class MSG_FolderInfoContainer; class MSG_FolderInfoMail; class MSG_IMAPHost; */ Loading Loading @@ -100,14 +99,8 @@ public: PRUint32 m_headerstartpos; nsByteArray m_headers; // char *m_headers; // PRUint32 m_headers_fp; // PRUint32 m_headers_size; nsByteArray m_envelope; // char *m_envelope; // PRUint32 m_envelope_fp; // PRUint32 m_envelope_size; struct message_header m_message_id; struct message_header m_references; Loading Loading @@ -232,18 +225,17 @@ private: }; #ifdef NEW_MAIL_HANDLED class ParseNewMailState : public ParseMailboxState class nsParseNewMailState : public nsMsgMailboxParser { public: ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail *folder); virtual ~ParseNewMailState(); nsParseNewMailState(MSG_Master *master, nsFilePath &folder); virtual ~nsParseNewMailState(); virtual void DoneParsingFolder(); virtual void SetUsingTempDB(PRBool usingTempDB, char *tmpDBName); void DisableFilters() {m_disableFilters = TRUE;} #ifdef DOING_FILTERS // from jsmsg.cpp friend void JSMailFilter_MoveMessage(ParseNewMailState *state, nsMsgHdr *msgHdr, Loading @@ -251,10 +243,11 @@ public: const char *folder, MSG_Filter *filter, PRBool *pMoved); XP_File GetLogFile(); nsInputFileStream *GetLogFile(); #endif // DOING_FILTERS protected: virtual PRInt32 PublishMsgHeader(); #ifdef DOING_FILTERS virtual void ApplyFilters(PRBool *pMoved); virtual MSG_FolderInfoMail *GetTrashFolder(); virtual int MoveIncorporatedMessage(nsMsgHdr *mailHdr, Loading @@ -264,12 +257,15 @@ protected: virtual int MarkFilteredMessageRead(nsMsgHdr *msgHdr); void LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr); MSG_FilterList *m_filterList; XP_File m_logFile; nsOutputFileStream *m_logFile; #endif // DOING_FILTERS char *m_tmpdbName; // Temporary filename of new database PRBool m_usingTempDB; PRBool m_disableFilters; }; #ifdef IMAP_NEW_MAIL_HANDLED class ParseIMAPMailboxState : public ParseNewMailState { Loading mailnews/local/src/nsPop3Protocol.cpp +13 −26 Original line number Diff line number Diff line Loading @@ -387,7 +387,7 @@ NS_IMETHODIMP nsPop3Protocol::OnStopBinding(nsIURL* aURL, nsresult aStatus, return NS_OK; // for now } nsPop3Protocol::nsPop3Protocol(nsIURL* aURL, nsITransport* aTransport) nsPop3Protocol::nsPop3Protocol(nsIURL* aURL, nsITransport* aTransport) : nsMsgLineBuffer(NULL, FALSE) { nsresult rv = 0; Loading Loading @@ -2038,15 +2038,6 @@ nsPop3Protocol::SendRetr() } extern PRInt32 msg_LineBuffer (const char *net_buffer, PRInt32 net_buffer_size, char **bufferP, PRUint32 *buffer_sizeP, PRUint32 *buffer_fpP, PRBool convert_newlines_p, PRInt32 (*per_line_fn) (char *line, PRUint32 line_length, void *closure), void *closure); static PRInt32 gPOP3parsed_bytes, gPOP3size; static PRBool gPOP3dotFix, gPOP3AssumedEnd; Loading Loading @@ -2175,10 +2166,7 @@ nsPop3Protocol::RetrResponse(nsIInputStream* inputStream, m_pop3ConData->obuffer_size = 1024; m_pop3ConData->obuffer_fp = 0; } status = msg_LineBuffer(buffer, buffer_size, &m_pop3ConData->obuffer, &m_pop3ConData->obuffer_size, &m_pop3ConData->obuffer_fp, PR_FALSE, RetrHandleLine, (void *) this); status = BufferInput(buffer, buffer_size); } if (status < 0) { Loading Loading @@ -2296,16 +2284,15 @@ nsPop3Protocol::TopResponse(nsIInputStream* inputStream, PRUint32 length) PRInt32 nsPop3Protocol::RetrHandleLine(char *line, PRUint32 line_length, void *closure) nsPop3Protocol::HandleLine(char *line, PRUint32 line_length) { nsPop3Protocol* p3p = (nsPop3Protocol *) closure; int status; PR_ASSERT(p3p->m_pop3ConData->msg_closure); if (!p3p->m_pop3ConData->msg_closure) PR_ASSERT(m_pop3ConData->msg_closure); if (!m_pop3ConData->msg_closure) return -1; if (p3p->m_pop3ConData->sender_info && !p3p->m_pop3ConData->seenFromHeader) if (m_pop3ConData->sender_info && !m_pop3ConData->seenFromHeader) { if (line_length > 6 && !XP_MEMCMP("From: ", line, 6)) { Loading @@ -2317,16 +2304,16 @@ nsPop3Protocol::RetrHandleLine(char *line, PRUint32 line_length, void *closure) */ char ch = line[line_length-1]; line[line_length-1] = 0; p3p->m_pop3ConData->seenFromHeader = PR_TRUE; if (PL_strstr(line, p3p->m_pop3ConData->sender_info) == NULL) p3p->m_nsIPop3Sink->SetSenderAuthedFlag(p3p->m_pop3ConData->msg_closure, m_pop3ConData->seenFromHeader = PR_TRUE; if (PL_strstr(line, m_pop3ConData->sender_info) == NULL) m_nsIPop3Sink->SetSenderAuthedFlag(m_pop3ConData->msg_closure, PR_FALSE); line[line_length-1] = ch; } } status = p3p->m_nsIPop3Sink->IncorporateWrite(p3p->m_pop3ConData->msg_closure, m_nsIPop3Sink->IncorporateWrite(m_pop3ConData->msg_closure, line, line_length); if ((status >= 0) && Loading @@ -2335,12 +2322,12 @@ nsPop3Protocol::RetrHandleLine(char *line, PRUint32 line_length, void *closure) { gPOP3AssumedEnd = PR_TRUE; /* in case byte count from server is */ /* wrong, mark we may have had the end */ if (!gPOP3dotFix || p3p->m_pop3ConData->truncating_cur_msg || if (!gPOP3dotFix || m_pop3ConData->truncating_cur_msg || (gPOP3parsed_bytes >= (gPOP3size -3))) { status = p3p->m_nsIPop3Sink->IncorporateComplete(p3p->m_pop3ConData->msg_closure); p3p->m_pop3ConData->msg_closure = 0; m_nsIPop3Sink->IncorporateComplete(m_pop3ConData->msg_closure); m_pop3ConData->msg_closure = 0; } } Loading mailnews/local/src/nsPop3Protocol.h +3 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "nsIInputStream.h" #include "nsIPop3URL.h" #include "nsIPop3Sink.h" #include "nsMsgLineBuffer.h" #include "rosetta.h" #include HG09893 Loading Loading @@ -291,7 +292,7 @@ typedef struct _Pop3ConData { char *sender_info; } Pop3ConData; class nsPop3Protocol : public nsIStreamListener class nsPop3Protocol : public nsIStreamListener, public nsMsgLineBuffer { public: nsPop3Protocol(nsIURL* aURL, nsITransport* aTransport); Loading Loading @@ -398,7 +399,7 @@ private: PRInt32 SendXsender(); PRInt32 XsenderResponse(); PRInt32 SendRetr(); static PRInt32 RetrHandleLine(char *line, PRUint32 line_length, void* closure); PRInt32 HandleLine(char *line, PRUint32 line_length); PRInt32 RetrResponse(nsIInputStream* inputStream, PRUint32 length); Loading mailnews/local/src/nsPop3Sink.cpp +36 −7 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "nscore.h" #include <stdio.h> #include <time.h> #include "nsParseMailbox.h" #ifdef XP_MAC # define LINEBREAK "\015" Loading Loading @@ -51,6 +52,7 @@ nsPop3Sink::nsPop3Sink() m_outputBuffer = nsnull; m_outputBufferSize = 0; m_mailDirectory = 0; m_newMailParser = NULL; #ifdef DEBUG m_fileCounter = 0; #endif Loading @@ -61,6 +63,8 @@ nsPop3Sink::~nsPop3Sink() PR_FREEIF(m_accountUrl); PR_FREEIF(m_outputBuffer); PR_FREEIF(m_mailDirectory); if (m_newMailParser) delete m_newMailParser; } nsresult Loading Loading @@ -121,6 +125,9 @@ nsPop3Sink::BeginMailDelivery(PRBool* aBool) nsFilePath filePath(path); m_outFileStream = new nsOutputFileStream(filePath, PR_WRONLY | PR_CREATE_FILE | PR_APPEND); // create a new mail parser m_newMailParser = new nsParseNewMailState(NULL, filePath); PR_FREEIF(path); #ifdef DEBUG Loading @@ -140,6 +147,12 @@ nsPop3Sink::EndMailDelivery() delete m_outFileStream; m_outFileStream = 0; } if (m_newMailParser) { delete m_newMailParser; m_newMailParser = NULL; } #ifdef DEBUG printf("End mail message delivery.\n"); #endif Loading Loading @@ -178,9 +191,9 @@ nsPop3Sink::IncorporateBegin(const char* uidlString, char *dummyEnvelope = GetDummyEnvelope(); *m_outFileStream << dummyEnvelope; *m_outFileStream << "X-Mozilla-Status: 8000\r\n"; *m_outFileStream << "X-Mozilla-Status2: 00000000\r\n"; WriteLineToMailbox(dummyEnvelope); WriteLineToMailbox("X-Mozilla-Status: 8000\r\n"); WriteLineToMailbox("X-Mozilla-Status2: 00000000\r\n"); return NS_OK; } Loading Loading @@ -254,8 +267,25 @@ nsPop3Sink::IncorporateWrite(void* closure, #ifdef DEBUG printf("%s\n", m_outputBuffer); #endif WriteLineToMailbox (m_outputBuffer); // Is this where we should hook up the new mail parser? Is this block a line, or a real block? // I think it's a real line. We're also not escaping lines that start with "From ", which is // a potentially horrible bug...Should this be done here, or in the mailbox parser? I vote for // here. Also, we're writing out the mozilla-status line in IncorporateBegin, but we need to // pass that along to the mailbox parser so that the mozilla-status offset is handled correctly. // And what about uidl? Don't we need to be able to write out an X-UIDL header? } return NS_OK; } nsresult nsPop3Sink::WriteLineToMailbox(char *buffer) { if (buffer) { if (m_newMailParser) m_newMailParser->ParseFolderLine(buffer, PL_strlen(buffer)); if (m_outFileStream) *m_outFileStream << m_outputBuffer; *m_outFileStream << buffer; } return NS_OK; } Loading @@ -275,8 +305,7 @@ nsPop3Sink::IncorporateComplete(void* closure) nsresult nsPop3Sink::IncorporateAbort(void* closure, PRInt32 status) { if (m_outFileStream) *m_outFileStream << LINEBREAK; WriteLineToMailbox(LINEBREAK); #ifdef DEBUG printf("Incorporate message abort.\n"); Loading Loading
mailnews/local/src/nsParseMailbox.cpp +263 −239 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ nsMsgMailboxParser::nsMsgMailboxParser() : nsMsgLineBuffer(NULL, PR_FALSE) nsMsgMailboxParser::~nsMsgMailboxParser() { XP_FREE(m_mailboxName); PR_FREEIF(m_mailboxName); } void nsMsgMailboxParser::UpdateStatusText () Loading Loading @@ -1223,187 +1223,23 @@ int nsParseMailMessageState::FinalizeHeaders() #ifdef NEW_MAIL_HANDLED int ParseNewMailState::MarkFilteredMessageRead(nsMsgHdr *msgHdr) nsParseNewMailState::nsParseNewMailState(MSG_Master *master, nsFilePath &folder) { if (m_mailDB) m_mailDB->MarkHdrRead(msgHdr, TRUE, NULL); else msgHdr->OrFlags(kIsRead); return 0; } int ParseNewMailState::MoveIncorporatedMessage(nsMsgHdr *mailHdr, nsMailDatabase *sourceDB, char *destFolder, MSG_Filter *filter) { int err = 0; XP_File destFid; XP_File sourceFid = m_file; // SetMaster(master); m_mailboxName = PL_strdup(folder); // Make sure no one else is writing into this folder MSG_FolderInfo *lockedFolder = m_mailMaster->FindMailFolder (destFolder, FALSE /*create*/); if (lockedFolder && (err = lockedFolder->AcquireSemaphore (this)) != 0) return err; if (sourceFid == 0) { sourceFid = XP_FileOpen(m_mailboxName, xpMailFolder, XP_FILE_READ_BIN); } XP_ASSERT(sourceFid != 0); if (sourceFid == 0) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); return MK_MSG_FOLDER_UNREADABLE; // ### dmb } XP_FileSeek (sourceFid, mailHdr->GetMessageOffset(), SEEK_SET); int newMsgPos; destFid = XP_FileOpen(destFolder, xpMailFolder, XP_FILE_APPEND_BIN); if (!destFid) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } if (!XP_FileSeek (destFid, 0, SEEK_END)) { newMsgPos = ftell (destFid); } else { XP_ASSERT(FALSE); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (destFid); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } nsMailDatabase *mailDb = NULL; // don't force upgrade in place - open the db here before we start writing to the // destination file because XP_Stat can return file size including bytes written... MsgERR msgErr = nsMailDatabase::Open (destFolder, TRUE, &mailDb); PRUint32 length = mailHdr->GetByteLength(); m_ibuffer_size = 10240; m_ibuffer = NULL; while (!m_ibuffer && (m_ibuffer_size >= 512)) { m_ibuffer = (char *) XP_ALLOC(m_ibuffer_size); if (m_ibuffer == NULL) m_ibuffer_size /= 2; } XP_ASSERT(m_ibuffer != NULL); while ((length > 0) && m_ibuffer) { PRUint32 nRead = XP_FileRead (m_ibuffer, length > m_ibuffer_size ? m_ibuffer_size : length, sourceFid); if (nRead == 0) break; // we must monitor the number of bytes actually written to the file. (mscott) if (XP_FileWrite (m_ibuffer, nRead, destFid) != nRead) { XP_FileClose(sourceFid); XP_FileClose(destFid); // truncate destination file in case message was partially written XP_FileTruncate(destFolder,xpMailFolder,newMsgPos); if (lockedFolder) lockedFolder->ReleaseSemaphore(this); if (mailDb) mailDb->Close(); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; // caller (ApplyFilters) currently ignores error conditions } // the new mail parser isn't going to get the stream input, it seems, so we can't use // the OnStartBinding mechanism the mailbox parser uses. So, let's open the db right now. nsMailDatabase::Open(folder, PR_TRUE, &m_mailDB, PR_FALSE); length -= nRead; } XP_ASSERT(length == 0); // if we have made it this far then the message has successfully been written to the new folder // now add the header to the mailDb. if (eSUCCESS == msgErr) { nsMsgHdr *newHdr = new nsMsgHdr(); if (newHdr) { newHdr->CopyFromMsgHdr (mailHdr, sourceDB->GetDB(), mailDb->GetDB()); // set new byte offset, since the offset in the old file is certainly wrong newHdr->SetMessageKey (newMsgPos); newHdr->OrFlags(kNew); msgErr = mailDb->AddHdrToDB (newHdr, NULL, m_updateAsWeGo); } } else { if (mailDb) { mailDb->Close(); mailDb = NULL; } } XP_FileClose(sourceFid); XP_FileClose(destFid); int truncRet = XP_FileTruncate(m_mailboxName, xpMailFolder, mailHdr->GetMessageOffset()); XP_ASSERT(truncRet >= 0); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); // tell outgoing parser that we've truncated the Inbox m_parseMsgState->Init(mailHdr->GetMessageOffset()); MSG_FolderInfo *folder = m_mailMaster->FindMailFolder(destFolder, FALSE); if (folder) folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); if (mailDb != NULL) { // update the folder size so we won't reparse. UpdateDBFolderInfo(mailDb, destFolder); if (folder != NULL) folder->SummaryChanged(); mailDb->Close(); } // We are logging the hit with the old mailHdr, which should work, as long // as LogRuleHit doesn't assume the new hdr. if (m_filterList->IsLoggingEnabled()) LogRuleHit(filter, mailHdr); return err; } ParseNewMailState::ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail *folder) : nsMsgMailboxParser(folder->GetPathname()) { SetMaster(master); #ifdef DOING_FILTERS if (MSG_FilterList::Open(master, filterInbox, NULL, folder, &m_filterList) != FilterError_Success) m_filterList = NULL; m_logFile = NULL; #endif #ifdef DOING_MDN if (m_filterList) { const char *folderName = NULL; Loading @@ -1424,7 +1260,6 @@ ParseNewMailState::ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail XP_FREE(defaultFolderName); } } if (folderName) { MSG_Filter *newFilter = new MSG_Filter(filterInboxRule, "receipt"); Loading Loading @@ -1453,29 +1288,109 @@ ParseNewMailState::ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail } } } m_logFile = NULL; #endif DOING_MDN m_usingTempDB = FALSE; m_tmpdbName = NULL; m_disableFilters = FALSE; } ParseNewMailState::~ParseNewMailState() nsParseNewMailState::~nsParseNewMailState() { #ifdef DOING_FILTERS if (m_filterList != NULL) MSG_CancelFilterList(m_filterList); if (m_logFile != NULL) XP_FileClose(m_logFile); #endif if (m_mailDB) m_mailDB->Close(); if (m_usingTempDB) // if (m_usingTempDB) // { // XP_FileRemove(m_tmpdbName, xpMailFolderSummary); // } PR_FREEIF(m_tmpdbName); #ifdef DOING_FILTERS JSFilter_cleanup(); #endif } // This gets called for every message because libnet calls IncorporateBegin, // IncorporateWrite (once or more), and IncorporateComplete for every message. void nsParseNewMailState::DoneParsingFolder() { PRBool moved = FALSE; /* End of file. Flush out any partial line remaining in the buffer. */ if (m_ibuffer_fp > 0) { XP_FileRemove(m_tmpdbName, xpMailFolderSummary); ParseFolderLine(m_ibuffer, m_ibuffer_fp); m_ibuffer_fp = 0; } FREEIF(m_tmpdbName); JSFilter_cleanup(); PublishMsgHeader(); if (!moved && m_mailDB != NULL) // finished parsing, so flush db folder info UpdateDBFolderInfo(); #ifdef HAVE_FOLDERINFO if (m_folder != NULL) m_folder->SummaryChanged(); #endif /* We're done reading the folder - we don't need these things any more. */ PR_FREEIF (m_ibuffer); m_ibuffer_size = 0; PR_FREEIF (m_obuffer); m_obuffer_size = 0; } XP_File ParseNewMailState::GetLogFile () PRInt32 nsParseNewMailState::PublishMsgHeader() { PRBool moved = FALSE; FinishHeader(); if (m_newMsgHdr) { FolderTypeSpecificTweakMsgHeader(m_newMsgHdr); #ifdef DOING_FILTERS if (!m_disableFilters) { ApplyFilters(&moved); } #endif // DOING_FILTERS if (!moved) { if (m_mailDB) { PRUint32 newFlags; m_newMsgHdr->OrFlags(MSG_FLAG_NEW, &newFlags); // m_mailDB->AddHdrToDB (m_newMsgHdr, NULL, // m_updateAsWeGo); } #ifdef HAVE_FOLDERINFO if (m_folder) m_folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); #endif } // if it was moved by imap filter, m_parseMsgState->m_newMsgHdr == NULL else if (m_newMsgHdr) { m_newMsgHdr->Release(); } m_newMsgHdr = NULL; } return 0; } void nsParseNewMailState::SetUsingTempDB(PRBool usingTempDB, char *tmpDBName) { m_usingTempDB = usingTempDB; m_tmpdbName = tmpDBName; } #ifdef DOING_FILTERS XP_File nsParseNewMailState::GetLogFile () { // This log file is used by regular filters and JS filters if (m_logFile == NULL) Loading @@ -1483,7 +1398,7 @@ XP_File ParseNewMailState::GetLogFile () return m_logFile; } void ParseNewMailState::LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr) void nsParseNewMailState::LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr) { char *filterName = ""; time_t date; Loading Loading @@ -1524,14 +1439,14 @@ void ParseNewMailState::LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr) } } MSG_FolderInfoMail *ParseNewMailState::GetTrashFolder() MSG_FolderInfoMail *nsParseNewMailState::GetTrashFolder() { MSG_FolderInfo *foundTrash = NULL; GetMaster()->GetLocalMailFolderTree()->GetFoldersWithFlag(MSG_FOLDER_FLAG_TRASH, &foundTrash, 1); return foundTrash ? foundTrash->GetMailFolderInfo() : (MSG_FolderInfoMail *)NULL; } void ParseNewMailState::ApplyFilters(PRBool *pMoved) void nsParseNewMailState::ApplyFilters(PRBool *pMoved) { MSG_Filter *filter; PRInt32 filterCount = 0; Loading Loading @@ -1694,75 +1609,184 @@ void ParseNewMailState::ApplyFilters(PRBool *pMoved) *pMoved = msgMoved; } // This gets called for every message because libnet calls IncorporateBegin, // IncorporateWrite (once or more), and IncorporateComplete for every message. void ParseNewMailState::DoneParsingFolder() int nsParseNewMailState::MarkFilteredMessageRead(nsMsgHdr *msgHdr) { PRBool moved = FALSE; /* End of file. Flush out any partial line remaining in the buffer. */ if (m_ibuffer_fp > 0) if (m_mailDB) m_mailDB->MarkHdrRead(msgHdr, TRUE, NULL); else msgHdr->OrFlags(kIsRead); return 0; } int nsParseNewMailState::MoveIncorporatedMessage(nsMsgHdr *mailHdr, nsMailDatabase *sourceDB, char *destFolder, MSG_Filter *filter) { m_parseMsgState->ParseFolderLine(m_ibuffer, m_ibuffer_fp); m_ibuffer_fp = 0; int err = 0; XP_File destFid; XP_File sourceFid = m_file; // Make sure no one else is writing into this folder MSG_FolderInfo *lockedFolder = m_mailMaster->FindMailFolder (destFolder, FALSE /*create*/); if (lockedFolder && (err = lockedFolder->AcquireSemaphore (this)) != 0) return err; if (sourceFid == 0) { sourceFid = XP_FileOpen(m_mailboxName, xpMailFolder, XP_FILE_READ_BIN); } PublishMsgHeader(); if (!moved && m_mailDB != NULL) // finished parsing, so flush db folder info UpdateDBFolderInfo(); XP_ASSERT(sourceFid != 0); if (sourceFid == 0) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); if (m_folder != NULL) m_folder->SummaryChanged(); return MK_MSG_FOLDER_UNREADABLE; // ### dmb } /* We're done reading the folder - we don't need these things any more. */ FREEIF (m_ibuffer); m_ibuffer_size = 0; FREEIF (m_obuffer); m_obuffer_size = 0; XP_FileSeek (sourceFid, mailHdr->GetMessageOffset(), SEEK_SET); int newMsgPos; destFid = XP_FileOpen(destFolder, xpMailFolder, XP_FILE_APPEND_BIN); if (!destFid) { #ifdef DEBUG_bienvenu XP_ASSERT(FALSE); #endif if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } PRInt32 ParseNewMailState::PublishMsgHeader() if (!XP_FileSeek (destFid, 0, SEEK_END)) { PRBool moved = FALSE; newMsgPos = ftell (destFid); } else { XP_ASSERT(FALSE); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); XP_FileClose (destFid); XP_FileClose (sourceFid); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; } m_parseMsgState->FinishHeader(); nsMailDatabase *mailDb = NULL; // don't force upgrade in place - open the db here before we start writing to the // destination file because XP_Stat can return file size including bytes written... MsgERR msgErr = nsMailDatabase::Open (destFolder, TRUE, &mailDb); PRUint32 length = mailHdr->GetByteLength(); if (m_parseMsgState->m_newMsgHdr) m_ibuffer_size = 10240; m_ibuffer = NULL; while (!m_ibuffer && (m_ibuffer_size >= 512)) { FolderTypeSpecificTweakMsgHeader(m_parseMsgState->m_newMsgHdr); if (!m_disableFilters) { ApplyFilters(&moved); m_ibuffer = (char *) XP_ALLOC(m_ibuffer_size); if (m_ibuffer == NULL) m_ibuffer_size /= 2; } if (!moved) XP_ASSERT(m_ibuffer != NULL); while ((length > 0) && m_ibuffer) { if (m_mailDB) PRUint32 nRead = XP_FileRead (m_ibuffer, length > m_ibuffer_size ? m_ibuffer_size : length, sourceFid); if (nRead == 0) break; // we must monitor the number of bytes actually written to the file. (mscott) if (XP_FileWrite (m_ibuffer, nRead, destFid) != nRead) { m_parseMsgState->m_newMsgHdr->OrFlags(kNew); m_mailDB->AddHdrToDB (m_parseMsgState->m_newMsgHdr, NULL, m_updateAsWeGo); XP_FileClose(sourceFid); XP_FileClose(destFid); // truncate destination file in case message was partially written XP_FileTruncate(destFolder,xpMailFolder,newMsgPos); if (lockedFolder) lockedFolder->ReleaseSemaphore(this); if (mailDb) mailDb->Close(); return MK_MSG_ERROR_WRITING_MAIL_FOLDER; // caller (ApplyFilters) currently ignores error conditions } if (m_folder) m_folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); length -= nRead; } } // if it was moved by imap filter, m_parseMsgState->m_newMsgHdr == NULL else if (m_parseMsgState->m_newMsgHdr) XP_ASSERT(length == 0); // if we have made it this far then the message has successfully been written to the new folder // now add the header to the mailDb. if (eSUCCESS == msgErr) { m_parseMsgState->m_newMsgHdr->unrefer(); nsMsgHdr *newHdr = new nsMsgHdr(); if (newHdr) { newHdr->CopyFromMsgHdr (mailHdr, sourceDB->GetDB(), mailDb->GetDB()); // set new byte offset, since the offset in the old file is certainly wrong newHdr->SetMessageKey (newMsgPos); newHdr->OrFlags(kNew); msgErr = mailDb->AddHdrToDB (newHdr, NULL, m_updateAsWeGo); } m_parseMsgState->m_newMsgHdr = NULL; } return 0; else { if (mailDb) { mailDb->Close(); mailDb = NULL; } } void ParseNewMailState::SetUsingTempDB(PRBool usingTempDB, char *tmpDBName) XP_FileClose(sourceFid); XP_FileClose(destFid); int truncRet = XP_FileTruncate(m_mailboxName, xpMailFolder, mailHdr->GetMessageOffset()); XP_ASSERT(truncRet >= 0); if (lockedFolder) lockedFolder->ReleaseSemaphore (this); // tell outgoing parser that we've truncated the Inbox m_parseMsgState->Init(mailHdr->GetMessageOffset()); MSG_FolderInfo *folder = m_mailMaster->FindMailFolder(destFolder, FALSE); if (folder) folder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); if (mailDb != NULL) { m_usingTempDB = usingTempDB; m_tmpdbName = tmpDBName; // update the folder size so we won't reparse. UpdateDBFolderInfo(mailDb, destFolder); if (folder != NULL) folder->SummaryChanged(); mailDb->Close(); } // We are logging the hit with the old mailHdr, which should work, as long // as LogRuleHit doesn't assume the new hdr. if (m_filterList->IsLoggingEnabled()) LogRuleHit(filter, mailHdr); return err; } #endif // DOING_FILTERS #ifdef IMAP_NEW_MAIL_HANDLED ParseIMAPMailboxState::ParseIMAPMailboxState(MSG_Master *master, MSG_IMAPHost *host, MSG_FolderInfoMail *folder, MSG_UrlQueue *urlQueue, TImapFlagAndUidState *flagStateAdopted) : ParseNewMailState(master, folder), fUrlQueue(urlQueue) : nsParseNewMailState(master, folder), fUrlQueue(urlQueue) { MSG_FolderInfoContainer *imapContainer = m_mailMaster->GetImapMailFolderTreeForHost(host->GetHostName()); MSG_FolderInfo *filteredFolder = imapContainer->FindMailPathname(folder->GetPathname()); Loading Loading @@ -1910,7 +1934,7 @@ MSG_FolderInfoMail *ParseIMAPMailboxState::GetTrashFolder() void ParseIMAPMailboxState::ApplyFilters(PRBool *pMoved) { if (fParsingInbox && !(GetCurrentMsg()->GetFlags() & kIsRead) ) ParseNewMailState::ApplyFilters(pMoved); nsParseNewMailState::ApplyFilters(pMoved); else *pMoved = FALSE; Loading Loading @@ -2184,4 +2208,4 @@ void ParseOutgoingMessage::FlushOutputBuffer() } } #endif /* NEW_MAIL_HANDLED */ #endif /* IMAP_NEW_MAIL_HANDLED */
mailnews/local/src/nsParseMailbox.h +24 −28 Original line number Diff line number Diff line Loading @@ -26,24 +26,23 @@ #include "nsMsgLineBuffer.h" #include "nsMsgRFC822Parser.h" class nsFilePath; class nsByteArray; class nsMailDatabase; class nsMsgHdr; class nsOutputFileStream; class nsInputFileStream; class MSG_Filter; class MSG_Master; class MSG_FolderInfoMail; class MSG_FilterList; /* class MSG_Master; class MailDB; class MSG_Pane; class MSG_FolderPane; class MailMessageHdr; struct MSG_FilterList; struct MSG_Filter; struct MSG_Rule; class MailMessageHdr; class MSG_UrlQueue; class TImapFlagAndUidState; class MSG_FolderInfoContainer; class MSG_FolderInfoMail; class MSG_IMAPHost; */ Loading Loading @@ -100,14 +99,8 @@ public: PRUint32 m_headerstartpos; nsByteArray m_headers; // char *m_headers; // PRUint32 m_headers_fp; // PRUint32 m_headers_size; nsByteArray m_envelope; // char *m_envelope; // PRUint32 m_envelope_fp; // PRUint32 m_envelope_size; struct message_header m_message_id; struct message_header m_references; Loading Loading @@ -232,18 +225,17 @@ private: }; #ifdef NEW_MAIL_HANDLED class ParseNewMailState : public ParseMailboxState class nsParseNewMailState : public nsMsgMailboxParser { public: ParseNewMailState(MSG_Master *master, MSG_FolderInfoMail *folder); virtual ~ParseNewMailState(); nsParseNewMailState(MSG_Master *master, nsFilePath &folder); virtual ~nsParseNewMailState(); virtual void DoneParsingFolder(); virtual void SetUsingTempDB(PRBool usingTempDB, char *tmpDBName); void DisableFilters() {m_disableFilters = TRUE;} #ifdef DOING_FILTERS // from jsmsg.cpp friend void JSMailFilter_MoveMessage(ParseNewMailState *state, nsMsgHdr *msgHdr, Loading @@ -251,10 +243,11 @@ public: const char *folder, MSG_Filter *filter, PRBool *pMoved); XP_File GetLogFile(); nsInputFileStream *GetLogFile(); #endif // DOING_FILTERS protected: virtual PRInt32 PublishMsgHeader(); #ifdef DOING_FILTERS virtual void ApplyFilters(PRBool *pMoved); virtual MSG_FolderInfoMail *GetTrashFolder(); virtual int MoveIncorporatedMessage(nsMsgHdr *mailHdr, Loading @@ -264,12 +257,15 @@ protected: virtual int MarkFilteredMessageRead(nsMsgHdr *msgHdr); void LogRuleHit(MSG_Filter *filter, nsMsgHdr *msgHdr); MSG_FilterList *m_filterList; XP_File m_logFile; nsOutputFileStream *m_logFile; #endif // DOING_FILTERS char *m_tmpdbName; // Temporary filename of new database PRBool m_usingTempDB; PRBool m_disableFilters; }; #ifdef IMAP_NEW_MAIL_HANDLED class ParseIMAPMailboxState : public ParseNewMailState { Loading
mailnews/local/src/nsPop3Protocol.cpp +13 −26 Original line number Diff line number Diff line Loading @@ -387,7 +387,7 @@ NS_IMETHODIMP nsPop3Protocol::OnStopBinding(nsIURL* aURL, nsresult aStatus, return NS_OK; // for now } nsPop3Protocol::nsPop3Protocol(nsIURL* aURL, nsITransport* aTransport) nsPop3Protocol::nsPop3Protocol(nsIURL* aURL, nsITransport* aTransport) : nsMsgLineBuffer(NULL, FALSE) { nsresult rv = 0; Loading Loading @@ -2038,15 +2038,6 @@ nsPop3Protocol::SendRetr() } extern PRInt32 msg_LineBuffer (const char *net_buffer, PRInt32 net_buffer_size, char **bufferP, PRUint32 *buffer_sizeP, PRUint32 *buffer_fpP, PRBool convert_newlines_p, PRInt32 (*per_line_fn) (char *line, PRUint32 line_length, void *closure), void *closure); static PRInt32 gPOP3parsed_bytes, gPOP3size; static PRBool gPOP3dotFix, gPOP3AssumedEnd; Loading Loading @@ -2175,10 +2166,7 @@ nsPop3Protocol::RetrResponse(nsIInputStream* inputStream, m_pop3ConData->obuffer_size = 1024; m_pop3ConData->obuffer_fp = 0; } status = msg_LineBuffer(buffer, buffer_size, &m_pop3ConData->obuffer, &m_pop3ConData->obuffer_size, &m_pop3ConData->obuffer_fp, PR_FALSE, RetrHandleLine, (void *) this); status = BufferInput(buffer, buffer_size); } if (status < 0) { Loading Loading @@ -2296,16 +2284,15 @@ nsPop3Protocol::TopResponse(nsIInputStream* inputStream, PRUint32 length) PRInt32 nsPop3Protocol::RetrHandleLine(char *line, PRUint32 line_length, void *closure) nsPop3Protocol::HandleLine(char *line, PRUint32 line_length) { nsPop3Protocol* p3p = (nsPop3Protocol *) closure; int status; PR_ASSERT(p3p->m_pop3ConData->msg_closure); if (!p3p->m_pop3ConData->msg_closure) PR_ASSERT(m_pop3ConData->msg_closure); if (!m_pop3ConData->msg_closure) return -1; if (p3p->m_pop3ConData->sender_info && !p3p->m_pop3ConData->seenFromHeader) if (m_pop3ConData->sender_info && !m_pop3ConData->seenFromHeader) { if (line_length > 6 && !XP_MEMCMP("From: ", line, 6)) { Loading @@ -2317,16 +2304,16 @@ nsPop3Protocol::RetrHandleLine(char *line, PRUint32 line_length, void *closure) */ char ch = line[line_length-1]; line[line_length-1] = 0; p3p->m_pop3ConData->seenFromHeader = PR_TRUE; if (PL_strstr(line, p3p->m_pop3ConData->sender_info) == NULL) p3p->m_nsIPop3Sink->SetSenderAuthedFlag(p3p->m_pop3ConData->msg_closure, m_pop3ConData->seenFromHeader = PR_TRUE; if (PL_strstr(line, m_pop3ConData->sender_info) == NULL) m_nsIPop3Sink->SetSenderAuthedFlag(m_pop3ConData->msg_closure, PR_FALSE); line[line_length-1] = ch; } } status = p3p->m_nsIPop3Sink->IncorporateWrite(p3p->m_pop3ConData->msg_closure, m_nsIPop3Sink->IncorporateWrite(m_pop3ConData->msg_closure, line, line_length); if ((status >= 0) && Loading @@ -2335,12 +2322,12 @@ nsPop3Protocol::RetrHandleLine(char *line, PRUint32 line_length, void *closure) { gPOP3AssumedEnd = PR_TRUE; /* in case byte count from server is */ /* wrong, mark we may have had the end */ if (!gPOP3dotFix || p3p->m_pop3ConData->truncating_cur_msg || if (!gPOP3dotFix || m_pop3ConData->truncating_cur_msg || (gPOP3parsed_bytes >= (gPOP3size -3))) { status = p3p->m_nsIPop3Sink->IncorporateComplete(p3p->m_pop3ConData->msg_closure); p3p->m_pop3ConData->msg_closure = 0; m_nsIPop3Sink->IncorporateComplete(m_pop3ConData->msg_closure); m_pop3ConData->msg_closure = 0; } } Loading
mailnews/local/src/nsPop3Protocol.h +3 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "nsIInputStream.h" #include "nsIPop3URL.h" #include "nsIPop3Sink.h" #include "nsMsgLineBuffer.h" #include "rosetta.h" #include HG09893 Loading Loading @@ -291,7 +292,7 @@ typedef struct _Pop3ConData { char *sender_info; } Pop3ConData; class nsPop3Protocol : public nsIStreamListener class nsPop3Protocol : public nsIStreamListener, public nsMsgLineBuffer { public: nsPop3Protocol(nsIURL* aURL, nsITransport* aTransport); Loading Loading @@ -398,7 +399,7 @@ private: PRInt32 SendXsender(); PRInt32 XsenderResponse(); PRInt32 SendRetr(); static PRInt32 RetrHandleLine(char *line, PRUint32 line_length, void* closure); PRInt32 HandleLine(char *line, PRUint32 line_length); PRInt32 RetrResponse(nsIInputStream* inputStream, PRUint32 length); Loading
mailnews/local/src/nsPop3Sink.cpp +36 −7 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "nscore.h" #include <stdio.h> #include <time.h> #include "nsParseMailbox.h" #ifdef XP_MAC # define LINEBREAK "\015" Loading Loading @@ -51,6 +52,7 @@ nsPop3Sink::nsPop3Sink() m_outputBuffer = nsnull; m_outputBufferSize = 0; m_mailDirectory = 0; m_newMailParser = NULL; #ifdef DEBUG m_fileCounter = 0; #endif Loading @@ -61,6 +63,8 @@ nsPop3Sink::~nsPop3Sink() PR_FREEIF(m_accountUrl); PR_FREEIF(m_outputBuffer); PR_FREEIF(m_mailDirectory); if (m_newMailParser) delete m_newMailParser; } nsresult Loading Loading @@ -121,6 +125,9 @@ nsPop3Sink::BeginMailDelivery(PRBool* aBool) nsFilePath filePath(path); m_outFileStream = new nsOutputFileStream(filePath, PR_WRONLY | PR_CREATE_FILE | PR_APPEND); // create a new mail parser m_newMailParser = new nsParseNewMailState(NULL, filePath); PR_FREEIF(path); #ifdef DEBUG Loading @@ -140,6 +147,12 @@ nsPop3Sink::EndMailDelivery() delete m_outFileStream; m_outFileStream = 0; } if (m_newMailParser) { delete m_newMailParser; m_newMailParser = NULL; } #ifdef DEBUG printf("End mail message delivery.\n"); #endif Loading Loading @@ -178,9 +191,9 @@ nsPop3Sink::IncorporateBegin(const char* uidlString, char *dummyEnvelope = GetDummyEnvelope(); *m_outFileStream << dummyEnvelope; *m_outFileStream << "X-Mozilla-Status: 8000\r\n"; *m_outFileStream << "X-Mozilla-Status2: 00000000\r\n"; WriteLineToMailbox(dummyEnvelope); WriteLineToMailbox("X-Mozilla-Status: 8000\r\n"); WriteLineToMailbox("X-Mozilla-Status2: 00000000\r\n"); return NS_OK; } Loading Loading @@ -254,8 +267,25 @@ nsPop3Sink::IncorporateWrite(void* closure, #ifdef DEBUG printf("%s\n", m_outputBuffer); #endif WriteLineToMailbox (m_outputBuffer); // Is this where we should hook up the new mail parser? Is this block a line, or a real block? // I think it's a real line. We're also not escaping lines that start with "From ", which is // a potentially horrible bug...Should this be done here, or in the mailbox parser? I vote for // here. Also, we're writing out the mozilla-status line in IncorporateBegin, but we need to // pass that along to the mailbox parser so that the mozilla-status offset is handled correctly. // And what about uidl? Don't we need to be able to write out an X-UIDL header? } return NS_OK; } nsresult nsPop3Sink::WriteLineToMailbox(char *buffer) { if (buffer) { if (m_newMailParser) m_newMailParser->ParseFolderLine(buffer, PL_strlen(buffer)); if (m_outFileStream) *m_outFileStream << m_outputBuffer; *m_outFileStream << buffer; } return NS_OK; } Loading @@ -275,8 +305,7 @@ nsPop3Sink::IncorporateComplete(void* closure) nsresult nsPop3Sink::IncorporateAbort(void* closure, PRInt32 status) { if (m_outFileStream) *m_outFileStream << LINEBREAK; WriteLineToMailbox(LINEBREAK); #ifdef DEBUG printf("Incorporate message abort.\n"); Loading