diff options
Diffstat (limited to 'kmailcvt/filter_oe.cxx')
-rw-r--r-- | kmailcvt/filter_oe.cxx | 429 |
1 files changed, 0 insertions, 429 deletions
diff --git a/kmailcvt/filter_oe.cxx b/kmailcvt/filter_oe.cxx deleted file mode 100644 index afd96527..00000000 --- a/kmailcvt/filter_oe.cxx +++ /dev/null @@ -1,429 +0,0 @@ -/*************************************************************************** - filter_oe.cxx - Outlook Express mail import - ------------------- - begin : Sat Feb 1 2003 - copyright : (C) 2003 by Laurence Anderson - (C) 2005 by Danny Kukawka - email : l.d.anderson@warwick.ac.uk - danny.Kukawka@web.de - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -// This filter was created by looking at libdbx & liboe - -#include <config.h> -#include <tdelocale.h> -#include <tdefiledialog.h> -#include <tdetempfile.h> -#include <kdebug.h> - -#include "filter_oe.hxx" - -#define OE4_SIG_1 0x36464d4a -#define OE4_SIG_2 0x00010003 -#define OE5_SIG_1 0xfe12adcf -#define OE5_EMAIL_SIG_2 0x6f74fdc5 -#define OE5_FOLDER_SIG_2 0x6f74fdc6 -#define OE5_SIG_3 0x11d1e366 -#define OE5_SIG_4 0xc0004e9a -#define MBX_MAILMAGIC 0x7F007F00 - -FilterOE::FilterOE() : - Filter( i18n("Import Outlook Express Emails"), - "Laurence Anderson <br>( Filter enhanced by Danny Kukawka )</p>", - i18n("<p><b>Outlook Express 4/5/6 import filter</b></p>" - "<p>You will need to locate the folder where the mailbox has been " - "stored by searching for .dbx or .mbx files under " - "<ul><li><i>C:\\Windows\\Application Data</i> in Windows 9x" - "<li><i>Documents and Settings</i> in Windows 2000 or later</ul></p>" - "<p><b>Note:</b> Since it is possible to recreate the folder structure, the folders from " - "Outlook Express 5 and 6 will be stored under: \"OE-Import\" in your local folder.</p>" )) -{} - -FilterOE::~FilterOE() -{ -} - -void FilterOE::import(FilterInfo *info) -{ - // Select directory containing plain text emails - mailDir = KFileDialog::getExistingDirectory(TQDir::homeDirPath(),info->parent()); - if (mailDir.isEmpty()) { // No directory selected - info->alert(i18n("No directory selected.")); - return; - } - - TQDir dir (mailDir); - TQStringList files = dir.entryList("*.[dDmM][bB][xX]", TQDir::Files, TQDir::Name); - if (files.isEmpty()) { - info->alert(i18n("No Outlook Express mailboxes found in directory %1.").arg(mailDir)); - return; - } - - totalFiles = files.count(); - currentFile = 0; - count0x04 = 0; - count0x84 = 0; - parsedFolder = false; - - info->setOverall(0); - - /** search the folderfile to recreate folder struct */ - for ( TQStringList::Iterator mailFile = files.begin(); mailFile != files.end(); ++mailFile ) { - if(*mailFile == "Folders.dbx") { - info->addLog(i18n("Import folder structure...")); - importMailBox(info, dir.filePath(*mailFile)); - if(!folderStructure.isEmpty()) parsedFolder = true; - // remove file from TQStringList::files, no longer needed - files.remove(mailFile); - currentIsFolderFile = false; - break; - } - } - - int n=0; - for ( TQStringList::Iterator mailFile = files.begin(); mailFile != files.end(); ++mailFile ) { - if ( info->shouldTerminate() ) break; - importMailBox(info, dir.filePath(*mailFile)); - info->setOverall(100 * ++n / files.count()); - } - - info->setOverall(100); - info->setCurrent(100); - info->addLog(i18n("Finished importing Outlook Express emails")); - if (info->shouldTerminate()) info->addLog( i18n("Finished import, canceled by user.")); - - kdDebug() << "\n" << "total emails in current file: " << totalEmails << endl; - kdDebug() << "0x84 Mails: " << count0x84 << endl; - kdDebug() << "0x04 Mails: " << count0x04 << endl; -} - -void FilterOE::importMailBox( FilterInfo *info, const TQString& fileName) -{ - TQFile mailfile(fileName); - TQFileInfo mailfileinfo(fileName); - TQString _nameOfFile = fileName; - _nameOfFile.remove( mailDir ); - _nameOfFile.remove( "/" ); - info->setFrom(mailfileinfo.fileName()); - - if (!mailfile.open(IO_ReadOnly)) { - info->addLog(i18n("Unable to open mailbox %1").arg(fileName)); - return; - } - TQDataStream mailbox(&mailfile); - mailbox.setByteOrder(TQDataStream::LittleEndian); - - // Parse magic - TQ_UINT32 sig_block1, sig_block2; - mailbox >> sig_block1 >> sig_block2; - if (sig_block1 == OE4_SIG_1 && sig_block2 == OE4_SIG_2) { - folderName = "OE-Import/" + mailfileinfo.baseName(TRUE); - info->addLog(i18n("Importing OE4 Mailbox %1").arg( "../" + _nameOfFile)); - info->setTo(folderName); - mbxImport(info, mailbox); - return; - } else { - TQ_UINT32 sig_block3, sig_block4; - mailbox >> sig_block3 >> sig_block4; - if (sig_block1 == OE5_SIG_1 && sig_block3 == OE5_SIG_3 && sig_block4 == OE5_SIG_4) { - if (sig_block2 == OE5_EMAIL_SIG_2) { - folderName = "OE-Import/" + mailfileinfo.baseName(TRUE); - if(parsedFolder) { - TQString _tmpFolder = getFolderName(_nameOfFile); - if(!_tmpFolder.isEmpty()) folderName = "OE-Import/" + _tmpFolder; - } - info->addLog(i18n("Importing OE5+ Mailbox %1").arg( "../" + _nameOfFile)); - info->setTo(folderName); - dbxImport(info, mailbox); - return; - } else if (sig_block2 == OE5_FOLDER_SIG_2) { - if(!parsedFolder) { - info->addLog(i18n("Importing OE5+ Folder file %1").arg( "../" + _nameOfFile)); - currentIsFolderFile = true; - dbxImport(info, mailbox); - currentIsFolderFile = false; - } - return; - } - } - } - // info->addLog(i18n("File %1 does not seem to be an Outlook Express mailbox").arg("../" + _nameOfFile)); -} - -/* ------------------- MBX support ------------------- */ - -void FilterOE::mbxImport( FilterInfo *info, TQDataStream& ds) -{ - TQ_UINT32 msgCount, lastMsgNum, fileSize; - - // Read the header - ds >> msgCount >> lastMsgNum >> fileSize; - ds.device()->at( ds.device()->at() + 64 ); // Skip 0's - kdDebug() << "This mailbox has " << msgCount << " messages" << endl; - if (msgCount == 0) - return; // Don't import empty mailbox - - TQ_UINT32 msgMagic; - ds >> msgMagic; // Read first magic - - while (!ds.atEnd()) { - TQ_UINT32 msgNumber, msgSize, msgTextSize; - KTempFile tmp; - tmp.dataStream()->setByteOrder(TQDataStream::LittleEndian); - - // Read the messages - ds >> msgNumber >> msgSize >> msgTextSize; // All seem to be lies...? - - do { - ds >> msgMagic; - if (msgMagic != MBX_MAILMAGIC) - *tmp.dataStream() << msgMagic; - else - break; - } while ( !ds.atEnd() ); - - tmp.close(); - /* comment by Danny Kukawka: - * addMessage() == old function, need more time and check for duplicates - * addMessage_fastImport == new function, faster and no check for duplicates - */ - if(info->removeDupMsg) - addMessage( info, folderName, tmp.name() ); - else - addMessage_fastImport( info, folderName, tmp.name() ); - - tmp.unlink(); - if(info->shouldTerminate()) return; - } -} - -/* ------------------- DBX support ------------------- */ - -void FilterOE::dbxImport( FilterInfo *info, TQDataStream& ds) -{ - // Get item count & offset of index - TQ_UINT32 itemCount, indexPtr; - ds.device()->at(0xc4); - ds >> itemCount; - ds.device()->at(0xe4); - ds >> indexPtr; - kdDebug() << "Item count is " << itemCount << ", Index at " << indexPtr << endl; - - if (itemCount == 0) - return; // Empty file - totalEmails = itemCount; - currentEmail = 0; - // Parse the indexes - ds.device()->at(indexPtr); - dbxReadIndex(info, ds, indexPtr); -} - -void FilterOE::dbxReadIndex( FilterInfo *info, TQDataStream& ds, int filePos) -{ - - if(info->shouldTerminate()) return; - TQ_UINT32 self, unknown, nextIndexPtr, parent, indexCount; - TQ_UINT8 unknown2, ptrCount; - TQ_UINT16 unknown3; - int wasAt = ds.device()->at(); - ds.device()->at(filePos); - - - kdDebug() << "Reading index of file " << folderName << endl; - ds >> self >> unknown >> nextIndexPtr >> parent >> unknown2 >> ptrCount >> unknown3 >> indexCount; // _dbx_tableindexstruct - - kdDebug() << "This index has " << (int) ptrCount << " data pointers" << endl; - for (int count = 0; count < ptrCount; count++) { - if(info->shouldTerminate()) return; - TQ_UINT32 dataIndexPtr, anotherIndexPtr, anotherIndexCount; // _dbx_indexstruct - ds >> dataIndexPtr >> anotherIndexPtr >> anotherIndexCount; - - if (anotherIndexCount > 0) { - kdDebug() << "Recursing to another table @ " << anotherIndexPtr << endl; - dbxReadIndex(info, ds, anotherIndexPtr); - } - kdDebug() << "Data index @ " << dataIndexPtr << endl; - dbxReadDataBlock(info, ds, dataIndexPtr); - } - - if (indexCount > 0) { // deal with nextTablePtr - kdDebug() << "Recuring to next table @ " << nextIndexPtr << endl; - dbxReadIndex(info, ds, nextIndexPtr); - } - - ds.device()->at(wasAt); // Restore file position to same as when function called -} - -void FilterOE::dbxReadDataBlock( FilterInfo *info, TQDataStream& ds, int filePos) -{ - TQ_UINT32 curOffset, blockSize; - TQ_UINT16 unknown; - TQ_UINT8 count, unknown2; - int wasAt = ds.device()->at(); - - TQString folderEntry[4]; - - ds.device()->at(filePos); - - ds >> curOffset >> blockSize >> unknown >> count >> unknown2; // _dbx_email_headerstruct - kdDebug() << "Data block has " << (int) count << " elements" << endl; - - for (int c = 0; c < count; c++) { - if(info->shouldTerminate()) return; - TQ_UINT8 type; // _dbx_email_pointerstruct - TQ_UINT32 value; // Actually 24 bit - - ds >> type >> value; - value &= 0xffffff; - ds.device()->at(ds.device()->at() - 1); // We only wanted 3 bytes - - if(!currentIsFolderFile) { - if (type == 0x84) { // It's an email! - kdDebug() << "**** Offset of emaildata (0x84) " << value << " ****" << endl; - dbxReadEmail(info, ds, value); - ++count0x84; - } else if( type == 0x04) { - int currentFilePos = ds.device()->at(); - ds.device()->at(filePos + 12 + value + (count*4) ); - TQ_UINT32 newOFF; - ds >> newOFF; - kdDebug() << "**** Offset of emaildata (0x04) " << newOFF << endl; - ds.device()->at(currentFilePos); - dbxReadEmail(info, ds, newOFF); - ++count0x04; - } - } - else { - // this is a folderfile - if(type == 0x02) { - // kdDebug() << "**** FOLDER: descriptive name ****" << endl; - folderEntry[0] = parseFolderString(ds, filePos + 12 + value + (count*4) ); - } else if (type == 0x03) { - // kdDebug() << "**** FOLDER: filename ****" << endl; - folderEntry[1] = parseFolderString(ds, filePos + 12 + value + (count*4) ); - - } else if (type == 0x80) { - // kdDebug() << "**** FOLDER: current ID ****" << endl; - folderEntry[2] = TQString::number(value); - - } else if (type == 0x81) { - // kdDebug() << "**** FOLDER: parent ID ****" << endl; - folderEntry[3] = TQString::number(value); - } - } - } - if(currentIsFolderFile) { - folderStructure.append(folderEntry); - } - ds.device()->at(wasAt); // Restore file position to same as when function called -} - -void FilterOE::dbxReadEmail( FilterInfo *info, TQDataStream& ds, int filePos) -{ - if(info->shouldTerminate()) return; - TQ_UINT32 self, nextAddressOffset, nextAddress=0; - TQ_UINT16 blockSize; - TQ_UINT8 intCount, unknown; - KTempFile tmp; - bool _break = false; - int wasAt = ds.device()->at(); - ds.device()->at(filePos); - - do { - ds >> self >> nextAddressOffset >> blockSize >> intCount >> unknown >> nextAddress; // _dbx_block_hdrstruct - TQByteArray blockBuffer(blockSize); - ds.readRawBytes(blockBuffer.data(), blockSize); - tmp.dataStream()->writeRawBytes(blockBuffer.data(), blockSize); - // to detect incomplete mails or corrupted archives. See Bug #86119 - if(ds.atEnd()) { - _break = true; - break; - } - ds.device()->at(nextAddress); - } while (nextAddress != 0); - tmp.close(); - - if(!_break) { - if(info->removeDupMsg) - addMessage( info, folderName, tmp.name() ); - else - addMessage_fastImport( info, folderName, tmp.name() ); - - currentEmail++; - int currentPercentage = (int) ( ( (float) currentEmail / totalEmails ) * 100 ); - info->setCurrent(currentPercentage); - ds.device()->at(wasAt); - } - tmp.unlink(); -} - -/* ------------------- FolderFile support ------------------- */ -TQString FilterOE::parseFolderString( TQDataStream& ds, int filePos ) -{ - char tmp; - TQString returnString; - int wasAt = ds.device()->at(); - ds.device()->at(filePos); - - // read while != 0x00 - while( !ds.device()->atEnd() ) { - tmp = ds.device()->getch(); - if( tmp != 0x00) { - returnString += tmp; - } - else break; - } - ds.device()->at(wasAt); - return returnString; -} - -/** get the foldername for a given file ID from folderMatrix */ -TQString FilterOE::getFolderName(TQString filename) -{ - bool found = false; - bool foundFilename = false; - TQString folder; - // we must do this because folder with more than one upper letter - // at start have maybe not a file named like the folder !!! - TQString search = filename.lower(); - - while (!found) - { - for ( FolderStructureIterator it = folderStructure.begin(); it != folderStructure.end(); it++) { - FolderStructure tmp = *it; - if(foundFilename == false) { - TQString _tmpFileName = tmp[1]; - _tmpFileName = _tmpFileName.lower(); - if(_tmpFileName == search) { - folder.prepend( tmp[0] + TQString::fromLatin1("/") ); - search = tmp[3]; - foundFilename = true; - } - } else { - TQString _currentID = tmp[2]; - TQString _parentID = tmp[3]; - if(_currentID == search) { - if(_parentID.isEmpty()) { // this is the root of the folder - found = true; - break; - } else { - folder.prepend( tmp[0] + TQString::fromLatin1("/") ); - search = tmp[3]; - } - } - } - } - // need to break the while loop maybe in some cases - if((foundFilename == false) && (folder.isEmpty())) return folder; - } - return folder; -} |