Fix for #73694. Parse and store date info from Eudora "From " lines and write out this date header for Eudora msgs which do not contain a "Date:" header. r=ducarroz, sr=sspitzer, a=asa.

This commit is contained in:
cavin%netscape.com 2002-03-04 23:40:16 +00:00
parent f83462be21
commit 26f97980ac
4 changed files with 61 additions and 39 deletions

View File

@ -1081,11 +1081,14 @@ nsresult nsEudoraCompose::WriteHeaders( nsIFileSpec *pDst, SimpleBufferTonyRCopi
nsresult rv = NS_OK; // it's ok if we don't have the first header on the predefined lists.
PRInt32 specialHeader;
PRBool specials[kMaxSpecialHeaders];
PRBool hasDateHeader = PR_FALSE;
int i;
for (i = 0; i < kMaxSpecialHeaders; i++)
specials[i] = PR_FALSE;
// m_pHeaders - contains headers from a Eudora msg.
// newHeaders - contains headers from a mozilla msg (more headers here).
do {
GetNthHeader( m_pHeaders, m_headerLen, n, header, val, PR_FALSE);
// GetNthHeader( newHeaders.m_pBuffer, newHeaders.m_writeOffset, n, header, val, PR_FALSE);
@ -1105,6 +1108,9 @@ nsresult nsEudoraCompose::WriteHeaders( nsIFileSpec *pDst, SimpleBufferTonyRCopi
val = replaceVal;
}
if (val.Length()) {
// See if we're writing out a Date: header.
if (!nsCRT::strcasecmp(header.get(), "Date"))
hasDateHeader = PR_TRUE;
rv = pDst->Write( header.get(), header.Length(), &written);
if (NS_SUCCEEDED( rv))
rv = pDst->Write( ": ", 2, &written);
@ -1118,6 +1124,14 @@ nsresult nsEudoraCompose::WriteHeaders( nsIFileSpec *pDst, SimpleBufferTonyRCopi
n++;
} while (NS_SUCCEEDED( rv) && (header.Length() != 0));
// If we don't have Date: header so far then use the default one (taken from Eudora "From " line).
if (!hasDateHeader)
{
rv = pDst->Write(m_defaultDate.get(), m_defaultDate.Length(), &written);
if (NS_SUCCEEDED( rv))
rv = pDst->Write( "\x0D\x0A", 2, &written);
}
for (i = 0; (i < kMaxSpecialHeaders) && NS_SUCCEEDED( rv); i++) {
if (!specials[i]) {
header = gSpecialHeaders[i];

View File

@ -114,6 +114,7 @@ public:
void SetBody( const char *pBody, PRInt32 len) { m_pBody = pBody; m_bodyLen = len;}
void SetHeaders( const char *pHeaders, PRInt32 len) { m_pHeaders = pHeaders; m_headerLen = len;}
void SetAttachments( nsVoidArray *pAttachments) { m_pAttachments = pAttachments;}
void SetDefaultDate( nsCString date) { m_defaultDate = date;}
nsresult CopyComposedMessage( nsCString& fromLine, nsIFileSpec *pSrc, nsIFileSpec *pDst, SimpleBufferTonyRCopiedOnce& copy);
@ -160,6 +161,7 @@ private:
nsString m_defCharset;
SimpleBufferTonyRCopiedOnce m_readHeaders;
nsCOMPtr<nsIImportService> m_pImportService;
nsCString m_defaultDate; // Use this if no Date: header in msgs
};

View File

@ -24,11 +24,13 @@
#include "nsEudoraMailbox.h"
#include "nsSpecialSystemDirectory.h"
#include "nsEudoraCompose.h"
#include "nspr.h"
#include "EudoraDebugLog.h"
#define kCopyBufferSize 8192
#define kMailReadBufferSize 16384
#define DATE_STR_LEN 64 // 64 bytes is plenty to hold the date header.
#define kWhitespace " \t\b\r\n"
@ -60,6 +62,31 @@ void DUMP_FILENAME( nsIFileSpec *pSpec, PRBool endLine)
#define DUMP_FILENAME( x, y)
#endif
static char *eudoraWeekDays[7] = {
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
};
static char *eudoraMonths[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
nsEudoraMailbox::nsEudoraMailbox()
{
@ -230,6 +257,7 @@ nsresult nsEudoraMailbox::ImportMailbox( PRUint32 *pBytes, PRBool *pAbort, const
if (NS_SUCCEEDED( rv = NS_NewFileSpec( getter_AddRefs( compositionFile)))) {
nsEudoraCompose compose;
nsCString defaultDate;
/*
IMPORT_LOG0( "Calling compose.SendMessage\n");
@ -244,7 +272,7 @@ nsresult nsEudoraMailbox::ImportMailbox( PRUint32 *pBytes, PRBool *pAbort, const
IMPORT_LOG0( "Reading first message\n");
while (!*pAbort && NS_SUCCEEDED( rv = ReadNextMessage( &state, readBuffer, headers, body))) {
while (!*pAbort && NS_SUCCEEDED( rv = ReadNextMessage( &state, readBuffer, headers, body, defaultDate))) {
if (pBytes) {
*pBytes += (((body.m_writeOffset - 1 + headers.m_writeOffset - 1) / div) * mul);
@ -253,6 +281,7 @@ nsresult nsEudoraMailbox::ImportMailbox( PRUint32 *pBytes, PRBool *pAbort, const
compose.SetBody( body.m_pBuffer, body.m_writeOffset - 1);
compose.SetHeaders( headers.m_pBuffer, headers.m_writeOffset - 1);
compose.SetAttachments( &m_attachments);
compose.SetDefaultDate(defaultDate);
rv = compose.SendTheMessage( compositionFile);
if (NS_SUCCEEDED( rv)) {
@ -402,7 +431,7 @@ nsresult nsEudoraMailbox::CompactMailbox( PRUint32 *pBytes, PRBool *pAbort, nsIF
nsresult nsEudoraMailbox::ReadNextMessage( ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header, SimpleBufferTonyRCopiedOnce& body)
nsresult nsEudoraMailbox::ReadNextMessage( ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header, SimpleBufferTonyRCopiedOnce& body, nsCString& defaultDate)
{
header.m_writeOffset = 0;
body.m_writeOffset = 0;
@ -419,7 +448,7 @@ nsresult nsEudoraMailbox::ReadNextMessage( ReadFileState *pState, SimpleBufferTo
IMPORT_LOG0( "*** Error, FillMailBuffer FAILED in ReadNextMessage\n");
return( rv);
}
lineLen = IsEudoraFromSeparator( copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset);
lineLen = IsEudoraFromSeparator( copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, defaultDate);
if (lineLen == -1) {
while ((lineLen = FindStartLine( copy)) == -1) {
@ -507,7 +536,8 @@ nsresult nsEudoraMailbox::ReadNextMessage( ReadFileState *pState, SimpleBufferTo
// Get the body!
// Read one line at a time here and look for the next separator
while ((lineLen = IsEudoraFromSeparator( copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset)) == -1) {
nsCString tmp;
while ((lineLen = IsEudoraFromSeparator( copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, tmp)) == -1) {
// 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.
@ -639,7 +669,7 @@ PRInt32 nsEudoraMailbox::IsEndHeaders( SimpleBufferTonyRCopiedOnce& data)
// versions of Eudora.
// A sample from line:
// From john@uxc.cso.uiuc.edu Wed Jan 14 12:36:18 1989
PRInt32 nsEudoraMailbox::IsEudoraFromSeparator( const char *pChar, PRInt32 maxLen)
PRInt32 nsEudoraMailbox::IsEudoraFromSeparator( const char *pChar, PRInt32 maxLen, nsCString& defaultDate)
{
if (maxLen < 12)
return( -1);
@ -718,7 +748,7 @@ PRInt32 nsEudoraMailbox::IsEudoraFromSeparator( const char *pChar, PRInt32 maxLe
int weekDay = 0;
int other = 0;
int result;
char tymStr[8];
char tymStr[9]; // Make it a null terminated string (used in PR_snprintf() call()).
PRBool tym = PR_FALSE;
PRBool remote = PR_FALSE;
PRBool from = PR_FALSE;
@ -795,6 +825,7 @@ PRInt32 nsEudoraMailbox::IsEudoraFromSeparator( const char *pChar, PRInt32 maxLe
tymStr[6] = '0';
tymStr[7] = '0';
}
tymStr[8] = 0;
}
else {
other++;
@ -848,12 +879,12 @@ PRInt32 nsEudoraMailbox::IsEudoraFromSeparator( const char *pChar, PRInt32 maxLe
}
// Whew!, the next line isn't blank.
/*
m_fromDay = day;
m_fromYear = year;
m_fromMonth = month;
m_fromWeekDay = weekDay;
*/
// Generate the default date header in case the date header is missing when we
// write out headers later. The header looks like "Date: Tue, 5 Feb 2002 23:05:04"
char date_header_str[DATE_STR_LEN];
PR_snprintf(date_header_str, DATE_STR_LEN, "Date: %s, %2d %s %4d %s", eudoraWeekDays[weekDay-1], day, eudoraMonths[month-1], year, tymStr);
defaultDate.Assign(date_header_str);
return( lineLen);
}
@ -875,31 +906,6 @@ PRInt32 nsEudoraMailbox::AsciiToLong( const char *pChar, PRInt32 len)
return( num);
}
static char *eudoraWeekDays[7] = {
"MON",
"TUE",
"WED",
"THU",
"FRI",
"SAT",
"SUN"
};
static char *eudoraMonths[12] = {
"JAN",
"FEB",
"MAR",
"APR",
"MAY",
"JUN",
"JUL",
"AUG",
"SEP",
"OCT",
"NOV",
"DEC"
};
int nsEudoraMailbox::IsWeekDayStr( const char *pStr)
{

View File

@ -50,7 +50,7 @@ public:
// import a mailbox
nsresult ImportMailbox( PRUint32 *pBytes, PRBool *pAbort, const PRUnichar *pName, nsIFileSpec *pSrc, nsIFileSpec *pDst, PRInt32 *pMsgCount);
static PRInt32 IsEudoraFromSeparator( const char *pData, PRInt32 maxLen);
static PRInt32 IsEudoraFromSeparator( const char *pData, PRInt32 maxLen, nsCString& defaultDate);
protected:
nsresult CreateTempFile( nsIFileSpec **ppSpec);
@ -59,7 +59,7 @@ protected:
private:
nsresult CompactMailbox( PRUint32 *pBytes, PRBool *pAbort, nsIFileSpec *pMail, nsIFileSpec *pToc, nsIFileSpec *pDst);
nsresult ReadNextMessage( ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header, SimpleBufferTonyRCopiedOnce& body);
nsresult ReadNextMessage( ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header, SimpleBufferTonyRCopiedOnce& body, nsCString& defaultDate);
PRInt32 FindStartLine( SimpleBufferTonyRCopiedOnce& data);
PRInt32 FindNextEndLine( SimpleBufferTonyRCopiedOnce& data);
PRInt32 IsEndHeaders( SimpleBufferTonyRCopiedOnce& data);