diff --git a/README.txt b/README.txt index 01b2699..332139d 100644 --- a/README.txt +++ b/README.txt @@ -2,6 +2,13 @@ Changes --- +v 1.0.3.10 + + - To improve mboxview, please post reviews on what works, what doesn't, create bug tickets and enhancment requests; + - Relaxed the mbox parsing rules in order to accept mbox files with different From_ line format that indicates starts of new mail; + - Corrected mail content when exporting to eml file; + - Updated User Manual to describe new and updated features; + v 1.0.3.9 - To improve mboxview, please post reviews on what works, what doesn't, create bug tickets and enhancment requests; diff --git a/ReadMe.markdown b/ReadMe.markdown index 22fa31e..1359dc4 100644 --- a/ReadMe.markdown +++ b/ReadMe.markdown @@ -38,6 +38,12 @@ The LICENSE.txt file was added in v1.0.3.4 to make the licensing explicit and to Changes --- +v 1.0.3.10 + + - To improve mboxview, please post reviews on what works, what doesn't, create bug tickets and enhancment requests; + - Relaxed the mbox parsing rules in order to accept mbox files with different From_ line format that indicates starts of new mail; + - Corrected mail content when exporting to eml file; + - Updated User Manual to describe new and updated features; v 1.0.3.9 diff --git a/UserGuide.odt b/UserGuide.odt index 4f1ae4c..1e573bc 100644 Binary files a/UserGuide.odt and b/UserGuide.odt differ diff --git a/UserGuide.pdf b/UserGuide.pdf index 548572b..f6b6027 100644 Binary files a/UserGuide.pdf and b/UserGuide.pdf differ diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index fca2e3b..debe247 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -360,6 +360,14 @@ void FileUtils::SplitFilePath(CString &fileName, CString &driveName, CString &di fileNameExtention.Append(ext); } +void FileUtils::GetFileExtension(CString &fileName, CString &fileNameExtention) +{ + CString driveName; + CString directory; + CString fileNameBase; + SplitFilePath(fileName, driveName, directory, fileNameBase, fileNameExtention); +} + void FileUtils::UpdateFileExtension(CString &fileName, CString &newExtension) { diff --git a/src/FileUtils.h b/src/FileUtils.h index e5e170f..f2cb1a0 100644 --- a/src/FileUtils.h +++ b/src/FileUtils.h @@ -53,6 +53,7 @@ class FileUtils static void CPathStripPathW(const wchar_t *path, CStringW &fileName); static BOOL CPathGetPath(const char *path, CString &filePath); static void SplitFilePath(CString &fileName, CString &driveName, CString &directory, CString &fileNameBase, CString &fileNameExtention); + static void GetFileExtension(CString &fileName, CString &fileNameExtention); static void UpdateFileExtension(CString &fileName, CString &newExtension); static _int64 FileSize(LPCSTR fileName); static BOOL BrowseToFileW(LPCWSTR filename); diff --git a/src/MboxMail.cpp b/src/MboxMail.cpp index ddbec0c..01ba330 100644 --- a/src/MboxMail.cpp +++ b/src/MboxMail.cpp @@ -209,12 +209,14 @@ BOOL MboxMail::GetBody(CString &res) //res = res.Mid(pos); // - 4); if (bAddCR) // for correct mime parsing { - TextUtilsEx::ReplaceNL2CRNL((LPCSTR)res + pos, res.GetLength() - pos, MboxMail::m_tmpbuf); + TextUtilsEx::ReplaceNL2CRNL((LPCSTR)res, res.GetLength(), MboxMail::m_tmpbuf); res.Empty(); res.Append(MboxMail::m_tmpbuf->Data(), MboxMail::m_tmpbuf->Count()); //res.Replace("\n", "\r\n"); } + else + int deb = 1; } fp.Close(); // TODO: verify why Close() was not called } @@ -259,6 +261,8 @@ bool IsFromValidDelimiter(char *p, char *e) { static int cnt = 0; + return true; + // EX_TEST #if 0 volatile char *badPtr = 0; @@ -349,11 +353,26 @@ bool MboxMail::Process(register char *p, DWORD bufSize, _int64 startOffset, boo char *badPtr = 0; + +#if 1 + if (bFirstView) + { + p = MimeParser::SkipEmptyLines(p, e); + if (!((TextUtilsEx::strncmpExact(p, e, cFromMailBegin, cFromMailBeginLen) == 0) && IsFromValidDelimiter(p, e))) // "From " marks beginning of the next mail + { + msgStart = p; + } + bEml = false; // not used below and not needed :) + } +#else if (bEml && bFirstView) { + p = MimeParser::SkipEmptyLines(p, e); msgStart = p; p += 5; + p = MimeParser::SkipEmptyLines(p, e); bEml = false; // not used below and not needed :) } +#endif CString progDir; BOOL retDir = GetProgramDir(progDir); @@ -660,7 +679,7 @@ bool MboxMail::Process(register char *p, DWORD bufSize, _int64 startOffset, boo // but it could be worst if we stop looking for headear fields prematuraly if (isEmpty) { - if (from.IsEmpty() || to.IsEmpty() || date.IsEmpty()) + if (from.IsEmpty() && to.IsEmpty() && date.IsEmpty()) int deb = 1; headerDone = TRUE; // skip remaining lines until next "From" or the end file diff --git a/src/MimeParser.cpp b/src/MimeParser.cpp index c3ce4a4..7cd082a 100644 --- a/src/MimeParser.cpp +++ b/src/MimeParser.cpp @@ -608,6 +608,18 @@ BOOL MimeParser::isEmptyLine(const char* p, const char* e) return FALSE; } +char* MimeParser::SkipEmptyLines(const char* p, const char* e) +{ + while (p < e) + { + if ((*p == '\r') || (*p == '\n') || (*p == ' ') || (*p == '\t')) // eat white + p++; + else + return (char*)p; + }; + return (char*)p; +} + char *MimeParser::EatNewLine(char* p, const char* e, BOOL &isEmpty) { isEmpty = TRUE; diff --git a/src/MimeParser.h b/src/MimeParser.h index 4be1fc5..9a30853 100644 --- a/src/MimeParser.h +++ b/src/MimeParser.h @@ -52,6 +52,7 @@ class MimeParser static int GetMessageId(CString &fieldLine, int startPos, CString &value); static int GetParamValue(CString &fieldLine, int startPos, const char *param, int paramLen, CString &value); static BOOL isEmptyLine(const char* p, const char* e); + static char* SkipEmptyLines(const char* p, const char* e); static char *EatNewLine(char* p, const char* e, BOOL &isEmpty); inline static char *EatNewLine(char* p, char*e) { diff --git a/src/NListView.cpp b/src/NListView.cpp index ad996b9..5bb6617 100644 --- a/src/NListView.cpp +++ b/src/NListView.cpp @@ -48,6 +48,7 @@ #include "SerializationHelper.h" #include "MimeHelper.h" #include "ColorStyleConfigDlg.h" +#include "MimeParser.h" #ifdef _DEBUG #undef THIS_FILE @@ -3161,9 +3162,21 @@ void NListView::SelectItem(int iItem) // Save raw message if (m_bExportEml) { + static const char *cFromMailBegin = "From "; + static const int cFromMailBeginLen = strlen(cFromMailBegin); // Save mail CFile fp(FileUtils::GetmboxviewTempPath() + "message.eml", CFile::modeWrite | CFile::modeCreate); - fp.Write(bdy, bdy.GetLength()); + char *pb = (char*)((LPCSTR)bdy); + int len = bdy.GetLength(); + char *e = pb + len; + char *p = MimeParser::SkipEmptyLines(pb, e); + if (TextUtilsEx::strncmpExact(p, e, cFromMailBegin, cFromMailBeginLen) == 0) + { + p = MimeParser::EatNewLine(p, e); + } + int eml_len = len - (p - pb); + fp.Write(p, eml_len); + //fp.Write(bdy, bdy.GetLength()); fp.Close(); } CString bdycharset = "UTF-8"; diff --git a/src/NTreeView.cpp b/src/NTreeView.cpp index 6145a79..0374c4a 100644 --- a/src/NTreeView.cpp +++ b/src/NTreeView.cpp @@ -121,35 +121,60 @@ void NTreeView::PostNcDestroy() // CWnd::PostNcDestroy(); } -#define BUFF_PREVIEW_SIZE 1024 +#define BUFF_PREVIEW_SIZE 10240 // This function checks whether file archive is valid // TODO: add MessageBox to report an error -BOOL ImboxviewFile(LPCSTR fileName) +BOOL ImboxviewFile(CString & fName) { + LPCSTR fileName = fName; + + // need better validation check; may need to parse the file BOOL bRet = FALSE; CFile fp; - int l = strlen(fileName); - if( l > 4 && _strnicmp(fileName + l - 4, ".eml", 4) == 0 ) + + CString fileNameExtention; + FileUtils::GetFileExtension(fName, fileNameExtention); + if (fileNameExtention.CompareNoCase(".eml") == 0) return TRUE; - char *buff = (char*)calloc(BUFF_PREVIEW_SIZE+1, 1); + + CString fileNameExtentionRoot = fileNameExtention.Mid(0, 5); + + if (fileNameExtentionRoot.CompareNoCase(".mbox") != 0) + return FALSE; + + char *buff = (char*)malloc(BUFF_PREVIEW_SIZE + 1); if( buff == NULL ) return FALSE; + if( ! fp.Open(fileName, CFile::modeRead) ) { free(buff); return FALSE; } - if( fp.Read(buff, BUFF_PREVIEW_SIZE) == 0 ) { - free(buff); - fp.Close(); - return FALSE; - } - if( strncmp(buff, "From ", 5) == 0 ) - bRet = TRUE; - else { - char * p = strstr(buff, "\nFrom "); - if( p != NULL ) + // Could do better -:) + for (int i = 0; i < 5000; i++) + { + UINT nCount = fp.Read(buff, BUFF_PREVIEW_SIZE); + if (nCount == 0) { + free(buff); + fp.Close(); + return FALSE; + } + buff[nCount] = 0; + if ((i == 0) && strncmp(buff, "From ", 5) == 0) + { bRet = TRUE; + break; + } + else + { + char * p = strstr(buff, "\nFrom "); + if (p != NULL) + { + bRet = TRUE; + break; + } + } } free(buff); fp.Close(); diff --git a/src/mboxview.rc b/src/mboxview.rc index 187d064..59df708 100644 --- a/src/mboxview.rc +++ b/src/mboxview.rc @@ -584,7 +584,7 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,3,8 + FILEVERSION 1,0,3,10 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG @@ -601,7 +601,7 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "mboxview MFC Application" - VALUE "FileVersion", "1.0.3.8" + VALUE "FileVersion", "1.0.3.10" VALUE "InternalName", "mboxview" VALUE "LegalCopyright", "Copyright (C) 2005" VALUE "OriginalFilename", "mboxview.EXE"