nsresult nsMovemailService::GetNewMail(nsIMsgWindow *aMsgWindow, nsIUrlListener *aUrlListener, nsIMsgFolder *aMsgFolder, nsIMovemailIncomingServer *movemailServer, nsIURI ** aURL) { LOG(("nsMovemailService::GetNewMail")); nsresult rv = NS_OK; nsCOMPtr<nsIMsgIncomingServer> in_server = do_QueryInterface(movemailServer); if (!in_server) return NS_MSG_INVALID_OR_MISSING_SERVER; mMsgWindow = aMsgWindow; // Attempt to locate the mail spool file nsCAutoString spoolPath; rv = LocateSpoolFile(spoolPath); if (NS_FAILED(rv) || spoolPath.IsEmpty()) { Error(MOVEMAIL_SPOOL_FILE_NOT_FOUND, nsnull, 0); return NS_ERROR_FAILURE; } // Create an input stream for the spool file nsCOMPtr<nsILocalFile> spoolFile; rv = NS_NewNativeLocalFile(spoolPath, true, getter_AddRefs(spoolFile)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIInputStream> spoolInputStream; rv = NS_NewLocalFileInputStream(getter_AddRefs(spoolInputStream), spoolFile); if (NS_FAILED(rv)) { const PRUnichar *params[] = { NS_ConvertUTF8toUTF16(spoolPath).get() }; Error(MOVEMAIL_CANT_OPEN_SPOOL_FILE, params, 1); return rv; } // Get a line input interface for the spool file nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(spoolInputStream, &rv); if (!lineInputStream) return rv; nsCOMPtr<nsIMsgFolder> serverFolder; nsCOMPtr<nsIMsgFolder> inbox; nsCOMPtr<nsIMsgFolder> rootMsgFolder; rv = in_server->GetRootFolder(getter_AddRefs(serverFolder)); NS_ENSURE_SUCCESS(rv, rv); rootMsgFolder = do_QueryInterface(serverFolder, &rv); if (!rootMsgFolder) return rv; rv = rootMsgFolder->GetFolderWithFlags(nsMsgFolderFlags::Inbox, getter_AddRefs(inbox)); NS_ENSURE_TRUE(inbox, NS_ERROR_FAILURE); nsCOMPtr <nsIOutputStream> outputStream; nsCOMPtr<nsIMsgPluggableStore> msgStore; rv = in_server->GetMsgStore(getter_AddRefs(msgStore)); NS_ENSURE_SUCCESS(rv, rv); bool reusable; nsCOMPtr<nsIMsgDBHdr> newHdr; msgStore->GetNewMsgOutputStream(inbox, getter_AddRefs(newHdr), &reusable, getter_AddRefs(outputStream)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr <nsIInputStream> inputStream = do_QueryInterface(outputStream); // create a new mail parser nsRefPtr<nsParseNewMailState> newMailParser = new nsParseNewMailState; NS_ENSURE_TRUE(newMailParser, NS_ERROR_OUT_OF_MEMORY); rv = newMailParser->Init(serverFolder, inbox, nsnull, newHdr, outputStream); NS_ENSURE_SUCCESS(rv, rv); in_server->SetServerBusy(true); // Try and obtain the lock for the spool file bool usingLockFile; if (!ObtainSpoolLock(spoolPath.get(), 5, &usingLockFile)) { nsAutoString lockFile = NS_ConvertUTF8toUTF16(spoolPath); lockFile.AppendLiteral(".lock"); const PRUnichar *params[] = { lockFile.get() }; Error(MOVEMAIL_CANT_CREATE_LOCK, params, 1); return NS_ERROR_FAILURE; } // MIDDLE of the FUN : consume the mailbox data. bool isMore = true; nsCAutoString buffer; PRUint32 bytesWritten; while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) { // If first string is empty and we're now at EOF then abort parsing. if (buffer.IsEmpty() && !isMore) { LOG(("Empty spool file")); break; } buffer += MSG_LINEBREAK; newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length()); outputStream->Write(buffer.get(), buffer.Length(), &bytesWritten); // 'From' lines delimit messages if (isMore && !strncmp(buffer.get(), "From ", 5)) { buffer.AssignLiteral("X-Mozilla-Status: 8000" MSG_LINEBREAK); newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length()); outputStream->Write(buffer.get(), buffer.Length(), &bytesWritten); buffer.AssignLiteral("X-Mozilla-Status2: 00000000" MSG_LINEBREAK); newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length()); outputStream->Write(buffer.get(), buffer.Length(), &bytesWritten); } } outputStream->Flush(); newMailParser->OnStopRequest(nsnull, nsnull, NS_OK); msgStore->FinishNewMessage(outputStream, newHdr); outputStream->Close(); // Truncate the spool file rv = spoolFile->SetFileSize(0); if (NS_FAILED(rv)) { const PRUnichar *params[] = { NS_ConvertUTF8toUTF16(spoolPath).get() }; Error(MOVEMAIL_CANT_TRUNCATE_SPOOL_FILE, params, 1); } if (!YieldSpoolLock(spoolPath.get(), usingLockFile)) { nsAutoString spoolLock = NS_ConvertUTF8toUTF16(spoolPath); spoolLock.AppendLiteral(".lock"); const PRUnichar *params[] = { spoolLock.get() }; Error(MOVEMAIL_CANT_DELETE_LOCK, params, 1); } in_server->SetServerBusy(false); LOG(("GetNewMail returning rv=%d", rv)); return rv; }
nsresult nsMovemailService::GetNewMail(nsIMsgWindow *aMsgWindow, nsIUrlListener *aUrlListener, nsIMsgFolder *aMsgFolder, nsIMovemailIncomingServer *movemailServer, nsIURI ** aURL) { LOG(("nsMovemailService::GetNewMail")); nsresult rv = NS_OK; nsCOMPtr<nsIMsgIncomingServer> in_server = do_QueryInterface(movemailServer); if (!in_server) return NS_MSG_INVALID_OR_MISSING_SERVER; mMsgWindow = aMsgWindow; // Attempt to locate the mail spool file nsCAutoString spoolPath; rv = LocateSpoolFile(spoolPath); if (NS_FAILED(rv) || spoolPath.IsEmpty()) { Error(MOVEMAIL_SPOOL_FILE_NOT_FOUND, nsnull, 0); return NS_ERROR_FAILURE; } // Create an input stream for the spool file nsCOMPtr<nsILocalFile> spoolFile; rv = NS_NewNativeLocalFile(spoolPath, PR_TRUE, getter_AddRefs(spoolFile)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIInputStream> spoolInputStream; rv = NS_NewLocalFileInputStream(getter_AddRefs(spoolInputStream), spoolFile); if (NS_FAILED(rv)) { const PRUnichar *params[] = { NS_ConvertUTF8toUCS2(spoolPath).get() }; Error(MOVEMAIL_CANT_OPEN_SPOOL_FILE, params, 1); return rv; } // Get a line input interface for the spool file nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(spoolInputStream, &rv); if (!lineInputStream) return rv; nsCOMPtr<nsIFileSpec> mailDirectory; rv = in_server->GetLocalPath(getter_AddRefs(mailDirectory)); NS_ENSURE_SUCCESS(rv, rv); nsFileSpec fileSpec; mailDirectory->GetFileSpec(&fileSpec); fileSpec += "Inbox"; nsIOFileStream outFileStream(fileSpec); outFileStream.seek(fileSpec.GetFileSize()); nsCOMPtr<nsIMsgFolder> serverFolder; nsCOMPtr<nsIMsgFolder> inbox; nsCOMPtr<nsIMsgFolder> rootMsgFolder; // create a new mail parser nsRefPtr<nsParseNewMailState> newMailParser = new nsParseNewMailState; if (newMailParser == nsnull) return NS_ERROR_OUT_OF_MEMORY; rv = in_server->GetRootFolder(getter_AddRefs(serverFolder)); NS_ENSURE_SUCCESS(rv, rv); rootMsgFolder = do_QueryInterface(serverFolder, &rv); if (!rootMsgFolder) return rv; PRUint32 numFolders; rv = rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, 1, &numFolders, getter_AddRefs(inbox)); NS_ENSURE_SUCCESS(rv, rv); rv = newMailParser->Init(serverFolder, inbox, fileSpec, &outFileStream, nsnull, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); in_server->SetServerBusy(PR_TRUE); // Try and obtain the lock for the spool file if (!ObtainSpoolLock(spoolPath.get(), 5)) { nsAutoString lockFile = NS_ConvertUTF8toUCS2(spoolPath); lockFile.AppendLiteral(".lock"); const PRUnichar *params[] = { lockFile.get() }; Error(MOVEMAIL_CANT_CREATE_LOCK, params, 1); return NS_ERROR_FAILURE; } // MIDDLE of the FUN : consume the mailbox data. PRBool isMore = PR_TRUE; nsCAutoString buffer; while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) { // If first string is empty and we're now at EOF then abort parsing. if (buffer.IsEmpty() && !isMore) { LOG(("Empty spool file")); break; } buffer += MSG_LINEBREAK; newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length()); outFileStream << buffer.get(); // 'From' lines delimit messages if (isMore && !strncmp(buffer.get(), "From ", 5)) { buffer.AssignLiteral("X-Mozilla-Status: 8000" MSG_LINEBREAK); newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length()); outFileStream << buffer.get(); buffer.AssignLiteral("X-Mozilla-Status2: 00000000" MSG_LINEBREAK); newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length()); outFileStream << buffer.get(); } } outFileStream.flush(); newMailParser->OnStopRequest(nsnull, nsnull, NS_OK); newMailParser->SetDBFolderStream(nsnull); // stream is going away if (outFileStream.is_open()) outFileStream.close(); // Truncate the spool file rv = spoolFile->SetFileSize(0); if (NS_FAILED(rv)) { const PRUnichar *params[] = { NS_ConvertUTF8toUCS2(spoolPath).get() }; Error(MOVEMAIL_CANT_TRUNCATE_SPOOL_FILE, params, 1); } if (!YieldSpoolLock(spoolPath.get())) { nsAutoString spoolLock = NS_ConvertUTF8toUCS2(spoolPath); spoolLock.AppendLiteral(".lock"); const PRUnichar *params[] = { spoolLock.get() }; Error(MOVEMAIL_CANT_DELETE_LOCK, params, 1); } in_server->SetServerBusy(PR_FALSE); LOG(("GetNewMail returning rv=%d", rv)); return rv; }