nsresult nsEudoraCompose::ReadHeaders( ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header) { // This should be the headers... header.m_writeOffset = 0; nsresult rv; PRInt32 lineLen; PRInt32 endLen = -1; PRInt8 endBuffer = 0; while ((endLen = IsEndHeaders( copy)) == -1) { while ((lineLen = FindNextEndLine( copy)) == -1) { copy.m_writeOffset = copy.m_bytesInBuf; if (!header.Write( copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0( "*** ERROR, writing headers\n"); return( NS_ERROR_FAILURE); } if (NS_FAILED( rv = FillMailBuffer( pState, copy))) { IMPORT_LOG0( "*** Error reading message headers\n"); return( rv); } if (!copy.m_bytesInBuf) { IMPORT_LOG0( "*** Error, end of file while reading headers\n"); return( NS_ERROR_FAILURE); } } copy.m_writeOffset += lineLen; if ((copy.m_writeOffset + 4) >= copy.m_bytesInBuf) { if (!header.Write( copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0( "*** ERROR, writing headers 2\n"); return( NS_ERROR_FAILURE); } if (NS_FAILED( rv = FillMailBuffer( pState, copy))) { IMPORT_LOG0( "*** Error reading message headers 2\n"); return( rv); } } } if (!header.Write( copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0( "*** Error writing final headers\n"); return( NS_ERROR_FAILURE); } if (!header.Write( (const char *)&endBuffer, 1)) { IMPORT_LOG0( "*** Error writing header trailing null\n"); return( NS_ERROR_FAILURE); } copy.m_writeOffset += endLen; return( NS_OK); }
nsresult nsEudoraCompose::CopyComposedMessage( nsCString& fromLine, nsIFile *pSrc, nsIOutputStream *pDst, SimpleBufferTonyRCopiedOnce& copy) { copy.m_bytesInBuf = 0; copy.m_writeOffset = 0; ReadFileState state; state.pFile = pSrc; state.offset = 0; state.size = 0; pSrc->GetFileSize( &state.size); if (!state.size) { IMPORT_LOG0( "*** Error, unexpected zero file size for composed message\n"); return( NS_ERROR_FAILURE); } nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(state.pInputStream), pSrc); if (NS_FAILED( rv)) { IMPORT_LOG0( "*** Error, unable to open composed message file\n"); return( NS_ERROR_FAILURE); } PRUint32 written; rv = pDst->Write( fromLine.get(), fromLine.Length(), &written); // well, isn't this a hoot! // Read the headers from the new message, get the ones we like // and write out only the headers we want from the new message, // along with all of the other headers from the "old" message! if (NS_SUCCEEDED( rv)) rv = FillMailBuffer( &state, copy); if (NS_SUCCEEDED( rv)) rv = ReadHeaders( &state, copy, m_readHeaders); if (NS_SUCCEEDED( rv)) { rv = WriteHeaders( pDst, m_readHeaders); } // We need to go ahead and write out the rest of the copy buffer // so that the following will properly copy the rest of the body char lastChar = 0; rv = EscapeFromSpaceLine(pDst, copy.m_pBuffer + copy.m_writeOffset, copy.m_pBuffer+copy.m_bytesInBuf); if (copy.m_bytesInBuf) lastChar = copy.m_pBuffer[copy.m_bytesInBuf - 1]; if (NS_SUCCEEDED(rv)) copy.m_writeOffset = copy.m_bytesInBuf; while ((state.offset < state.size) && NS_SUCCEEDED( rv)) { rv = FillMailBuffer( &state, copy); if (NS_SUCCEEDED( rv)) { rv = EscapeFromSpaceLine(pDst, copy.m_pBuffer + copy.m_writeOffset, copy.m_pBuffer+copy.m_bytesInBuf); lastChar = copy.m_pBuffer[copy.m_bytesInBuf - 1]; if (NS_SUCCEEDED( rv)) copy.m_writeOffset = copy.m_bytesInBuf; else IMPORT_LOG0( "*** Error writing to destination mailbox\n"); } } state.pInputStream->Close(); if ((lastChar != 0x0A) && NS_SUCCEEDED( rv)) { rv = pDst->Write( "\x0D\x0A", 2, &written); if (written != 2) rv = NS_ERROR_FAILURE; } return( rv); }
nsresult nsEudoraMailbox::ReadNextMessage(ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header, SimpleBufferTonyRCopiedOnce& body, nsCString& defaultDate, nsCString& bodyType, EudoraTOCEntry *pTocEntry) { header.m_writeOffset = 0; body.m_writeOffset = 0; nsresult rv; int32_t lineLen; char endBuffer = 0; lineLen = -1; // Find the from separator - we should actually be positioned at the // from separator, but for now, we'll verify this. while (lineLen == -1) { if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error, FillMailBuffer FAILED in ReadNextMessage\n"); return rv; } lineLen = IsEudoraFromSeparator(copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, defaultDate); if (lineLen == -1) { while ((lineLen = FindStartLine(copy)) == -1) { copy.m_writeOffset = copy.m_bytesInBuf; if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error, FillMailBuffer FAILED in ReadNextMessage, looking for next start line\n"); return rv; } if (!copy.m_bytesInBuf) { IMPORT_LOG0("*** Error, ReadNextMessage, looking for start of next line, got end of file.\n"); return NS_ERROR_FAILURE; } } copy.m_writeOffset += lineLen; lineLen = -1; } } // Skip past the from line separator while ((lineLen = FindStartLine(copy)) == -1) { copy.m_writeOffset = copy.m_bytesInBuf; if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error, ReadNextMessage, FillMailBuffer failed looking for from sep\n"); return rv; } if (!copy.m_bytesInBuf) { IMPORT_LOG0("*** Error, ReadNextMessage, end of file looking for from sep\n"); return NS_ERROR_FAILURE; } } copy.m_writeOffset += lineLen; if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error, Unable to fill mail buffer after from sep.\n"); return rv; } // This should be the headers... int32_t endLen = -1; while ((endLen = IsEndHeaders(copy)) == -1) { while ((lineLen = FindNextEndLine(copy)) == -1) { copy.m_writeOffset = copy.m_bytesInBuf; if (!header.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** ERROR, writing headers\n"); return NS_ERROR_FAILURE; } if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error reading message headers\n"); return rv; } if (!copy.m_bytesInBuf) { IMPORT_LOG0("*** Error, end of file while reading headers\n"); return NS_ERROR_FAILURE; } } copy.m_writeOffset += lineLen; if ((copy.m_writeOffset + 4) >= copy.m_bytesInBuf) { if (!header.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** ERROR, writing headers 2\n"); return NS_ERROR_FAILURE; } if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error reading message headers 2\n"); return rv; } } } if (!header.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** Error writing final headers\n"); return NS_ERROR_FAILURE; } if (pTocEntry) { // This is not the prettiest spot to stick this code, but it works and it was convenient. char header_str[128]; // Write X-Mozilla-Status header PR_snprintf(header_str, 128, MSG_LINEBREAK X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, pTocEntry->GetMozillaStatusFlags()); header.Write(header_str, strlen(header_str)); // Write X-Mozilla-Status2 header PR_snprintf(header_str, 128, X_MOZILLA_STATUS2_FORMAT MSG_LINEBREAK, pTocEntry->GetMozillaStatus2Flags()); header.Write(header_str, strlen(header_str)); // Format and write X-Mozilla-Keys header nsCString keywordHdr(X_MOZILLA_KEYWORDS); if (pTocEntry->HasEudoraLabel()) { PR_snprintf(header_str, 128, "eudoralabel%d", pTocEntry->GetLabelNumber()); keywordHdr.Replace(sizeof(HEADER_X_MOZILLA_KEYWORDS) + 1, strlen(header_str), header_str); } header.Write(keywordHdr.get(), keywordHdr.Length()); } if (!header.Write(&endBuffer, 1)) { IMPORT_LOG0("*** Error writing header trailing null\n"); return NS_ERROR_FAILURE; } copy.m_writeOffset += endLen; if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error reading beginning of message body\n"); return rv; } EmptyAttachments(); // Get the body! // Read one line at a time here and look for the next separator nsCString tmp; bool insideEudoraTags = false; // by default we consider the body text to be plain text bodyType = "text/plain"; while ((lineLen = IsEudoraFromSeparator(copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, tmp)) == -1) { int32_t tagLength = 0; if (IsEudoraTag (copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, insideEudoraTags, bodyType, tagLength)) { // We don't want to keep eudora tags so skip over them. // let's write the previous text if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** Error writing to message body\n"); return NS_ERROR_FAILURE; } // we want to skip over the tag...for now we are assuming the tag is always at the start of line. copy.m_writeOffset += tagLength; if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error reading message body\n"); return rv; } if (!copy.m_bytesInBuf) break; continue; } // Eudora Attachment lines are always outside Eudora Tags // so we shouldn't try to find one here if (!insideEudoraTags) { // Debatable is whether or not to exclude these lines from the // text of the message, I prefer not to in case the original // attachment is actually missing. rv = ExamineAttachment(copy); if (NS_FAILED(rv)) { IMPORT_LOG0("*** Error examining attachment line\n"); return rv; } } while (((lineLen = FindStartLine(copy)) == -1) && copy.m_bytesInBuf) { copy.m_writeOffset = copy.m_bytesInBuf; if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** Error writing to message body\n"); return NS_ERROR_FAILURE; } if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error reading message body\n"); return rv; } } if (!copy.m_bytesInBuf) break; copy.m_writeOffset += lineLen; // found the start of the next line // make sure it's long enough to check for the from line if ((copy.m_writeOffset + 2048) >= copy.m_bytesInBuf) { if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** Error writing to message body 2\n"); return NS_ERROR_FAILURE; } if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error reading message body 2\n"); return rv; } } } // the start of the current line is a from, we-re done if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) { IMPORT_LOG0("*** Error writing final message body\n"); return NS_ERROR_FAILURE; } if (!body.Write(&endBuffer, 1)) { IMPORT_LOG0("*** Error writing body trailing null\n"); IMPORT_LOG2("\tbody.m_size: %ld, body.m_writeOffset: %ld\n", body.m_size, body.m_writeOffset); return NS_ERROR_FAILURE; } if (NS_FAILED(rv = FillMailBuffer(pState, copy))) { IMPORT_LOG0("*** Error filling mail buffer for next read message\n"); return rv; } return NS_OK; }