From 685cd9b33a012511689f797fb389b6ad2d2f21c2 Mon Sep 17 00:00:00 2001 From: Arshad Ali Abdul Samad Date: Wed, 30 May 2018 10:59:03 +0800 Subject: [PATCH] removed fs --- package.json | 1 - src/PSTFile/PSTFile.class.ts | 45 +----- src/PSTFile/PSTFile.spec.ts | 7 +- src/test-min.ts | 64 --------- src/test.ts | 269 ----------------------------------- 5 files changed, 7 insertions(+), 379 deletions(-) delete mode 100644 src/test-min.ts delete mode 100644 src/test.ts diff --git a/package.json b/package.json index 3bdae1e..9c41bad 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,5 @@ "dependencies": { "long": "^4.0.0", "uuid-parse": "^1.0.0", - "winston": "^2.4.1" } } diff --git a/src/PSTFile/PSTFile.class.ts b/src/PSTFile/PSTFile.class.ts index 57e6392..6911739 100644 --- a/src/PSTFile/PSTFile.class.ts +++ b/src/PSTFile/PSTFile.class.ts @@ -41,7 +41,6 @@ import { PSTObject } from '../PSTObject/PSTObject.class'; import { PSTTableBC } from '../PSTTableBC/PSTTableBC.class'; import { PSTTableItem } from '../PSTTableItem/PSTTableItem.class'; import { PSTUtil } from '../PSTUtil/PSTUtil.class'; -import * as fs from 'fs'; import * as util from 'util'; import * as long from 'long'; const uuidparse = require('uuid-parse'); @@ -97,20 +96,12 @@ export class PSTFile { return this._pstFileType; } - private _pstFilename: string = ''; - public get pstFilename(): string { - return this._pstFilename; - } - // b-tree private childrenDescriptorTree: Map | null = null; // node tree maps private static nodeMap: NodeMap = new NodeMap(); - // file descriptor - private pstFD: number; - // in-memory file buffer (instead of filesystem) private pstBuffer: Buffer = new Buffer(0); @@ -119,21 +110,12 @@ export class PSTFile { /** * Creates an instance of PSTFile. File is opened in constructor. - * @param {string} fileName + * @param {Buffer} pstBuffer * @memberof PSTFile */ public constructor(pstBuffer: Buffer); - public constructor(fileName: string); - public constructor(arg: any) { - if (arg instanceof Buffer) { - // use an in-memory buffer of PST - this.pstBuffer = arg; - this.pstFD = -1; - } else { - // use PST in filesystem - this._pstFilename = arg; - this.pstFD = fs.openSync(this._pstFilename, 'r'); - } + // use an in-memory buffer of PST + this.pstBuffer = arg; // confirm first 4 bytes are !BDN let buffer = new Buffer(514); @@ -166,16 +148,6 @@ export class PSTFile { this.processNameToIDMap(); } - /** - * Close the file. - * @memberof PSTFile - */ - public close() { - if (this.pstFD > 0) { - fs.closeSync(this.pstFD); - } - } - /** * Process name to ID map. * @private @@ -828,14 +800,9 @@ export class PSTFile { * @memberof PSTFile */ private readSync(buffer: Buffer, length: number, position: number): number { - if (this.pstFD > 0) { - // read from file system - return fs.readSync(this.pstFD, buffer, 0, length, position); - } else { - // copy from in-memory buffer - this.pstBuffer.copy(buffer, 0, position, position + length); - return length; - } + // copy from in-memory buffer + this.pstBuffer.copy(buffer, 0, position, position + length); + return length; } /** diff --git a/src/PSTFile/PSTFile.spec.ts b/src/PSTFile/PSTFile.spec.ts index 3f66ce7..30e63b4 100644 --- a/src/PSTFile/PSTFile.spec.ts +++ b/src/PSTFile/PSTFile.spec.ts @@ -6,18 +6,13 @@ const expect = chai.expect; let pstFile: PSTFile; before(() => { - pstFile = new PSTFile(resolve('./src/testdata/michelle_lokay_000_1_1_1_1.pst')); -}); - -after(() => { - pstFile.close(); + pstFile = new PSTFile(fs.readFileSync('./src/testdata/michelle_lokay_000_1_1_1_1.pst')); }); describe('PSTfile tests', () => { it('should open the file', () => { expect(pstFile.encryptionType).to.equal(1); expect(pstFile.pstFileType).to.equal(23); - expect(pstFile.pstFilename).to.contain('michelle_lokay_000_1_1_1_1.pst'); expect(pstFile.getMessageStore().displayName).to.equal('Personal folders'); expect(pstFile.getRootFolder()).to.not.be.null; }); diff --git a/src/test-min.ts b/src/test-min.ts deleted file mode 100644 index d893170..0000000 --- a/src/test-min.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { PSTMessage } from './PSTMessage/PSTMessage.class'; -import { PSTFile } from './PSTFile/PSTFile.class'; -import { PSTFolder } from './PSTFolder/PSTFolder.class'; -const resolve = require('path').resolve; - -let depth = -1; -let col = 0; - -const pstFile = new PSTFile(resolve('./src/testdata/michelle_lokay_000_1_1_1_1.pst')); -console.log(pstFile.getMessageStore().displayName); -processFolder(pstFile.getRootFolder()); - -/** - * Walk the folder tree recursively and process emails. - * @param {PSTFolder} folder - */ -function processFolder(folder: PSTFolder) { - depth++; - - // the root folder doesn't have a display name - if (depth > 0) { - console.log(getDepth(depth) + folder.displayName); - } - - // go through the folders... - if (folder.hasSubfolders) { - let childFolders: PSTFolder[] = folder.getSubFolders(); - for (let childFolder of childFolders) { - processFolder(childFolder); - } - } - - // and now the emails for this folder - if (folder.contentCount > 0) { - depth++; - let email: PSTMessage = folder.getNextChild(); - while (email != null) { - console.log(getDepth(depth) + - 'Sender: ' + email.senderName + - ', Subject: ' + email.subject); - email = folder.getNextChild(); - } - depth--; - } - depth--; -} - -/** - * Returns a string with visual indication of depth in tree. - * @param {number} depth - * @returns {string} - */ -function getDepth(depth: number): string { - let sdepth = ''; - if (col > 0) { - col = 0; - sdepth += '\n'; - } - for (let x = 0; x < depth - 1; x++) { - sdepth += ' | '; - } - sdepth += ' |- '; - return sdepth; -} diff --git a/src/test.ts b/src/test.ts deleted file mode 100644 index 270e22c..0000000 --- a/src/test.ts +++ /dev/null @@ -1,269 +0,0 @@ -/** - * Copyright 2010-2018 Richard Johnson, Orin Eman & Ed Pfromer - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * --- - * - * This file is part of pst-extractor. - * - * pst-extractor is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * pst-extractor is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with pst-extractor. If not, see . - */ -import { PSTMessage } from './PSTMessage/PSTMessage.class'; -import { PSTFile } from './PSTFile/PSTFile.class'; -import { PSTFolder } from './PSTFolder/PSTFolder.class'; -import { PSTAttachment } from './PSTAttachment/PSTAttachment.class'; -import * as fs from 'fs'; -import { PSTRecipient } from './PSTRecipient/PSTRecipient.class'; - -const pstFolder = '/media/sf_Outlook/test/'; -const topOutputFolder = '/media/sf_Outlook/pst-extractor/'; -let outputFolder = ''; -const saveToFS = false; -const displaySender = true; -const displayRecipients = true; -const displayBody = false; -const verbose = true; -let depth = -1; -let col = 0; - -// make a top level folder to hold content -try { - if (saveToFS) { - fs.mkdirSync(topOutputFolder); - } -} catch (err) { - console.error(err); -} - -let directoryListing = fs.readdirSync(pstFolder); -directoryListing.forEach(filename => { - console.log(pstFolder + filename); - - // time for performance comparison to Java and improvement - const start = Date.now(); - let pstFile = new PSTFile(pstFolder + filename); - - // make a sub folder for each PST - try { - if (saveToFS) { - outputFolder = topOutputFolder + filename + '/'; - fs.mkdirSync(outputFolder); - } - } catch (err) { - console.error(err); - } - - console.log(pstFile.getMessageStore().displayName); - processFolder(pstFile.getRootFolder()); - - const end = Date.now(); - console.log('processed in ' + (end - start) + ' ms'); -}); - -/** - * Walk the folder tree recursively and process emails. - * @param {PSTFolder} folder - */ -function processFolder(folder: PSTFolder) { - depth++; - - // the root folder doesn't have a display name - if (depth > 0) { - console.log(getDepth(depth) + folder.displayName); - } - - // go through the folders... - if (folder.hasSubfolders) { - let childFolders: PSTFolder[] = folder.getSubFolders(); - for (let childFolder of childFolders) { - processFolder(childFolder); - } - } - - // and now the emails for this folder - if (folder.contentCount > 0) { - depth++; - let email: PSTMessage = folder.getNextChild(); - while (email != null) { - if (verbose) { - console.log(getDepth(depth) + 'Email: ' + email.descriptorNodeId + ' - ' + email.subject); - } else { - printDot(); - } - - // sender - let sender = getSender(email); - - // recipients - let recipients = getRecipients(email); - - // display body? - if (verbose && displayBody) { - console.log(email.body); - console.log(email.bodyRTF); - } - - // save content to fs? - if (saveToFS) { - // create date string in format YYYY-MM-DD - let strDate = ''; - let d = email.clientSubmitTime; - if (!d && email.creationTime) { - d = email.creationTime; - } - if (d) { - const month = ('0' + (d.getMonth()+1)).slice(-2); - const day = ('0' + d.getDate()).slice(-2); - strDate = d.getFullYear() + '-' + month + '-' + day; - } - - // create a folder for each day (client submit time) - const emailFolder = outputFolder + strDate + '/'; - if (!fs.existsSync(emailFolder)) { - try { - fs.mkdirSync(emailFolder); - } catch (err) { - console.error(err); - } - } - - doSaveToFS(email, emailFolder, sender, recipients); - } - email = folder.getNextChild(); - } - depth--; - } - depth--; -} - -/** - * Save items to filesystem. - * @param {PSTMessage} msg - * @param {string} emailFolder - * @param {string} sender - * @param {string} recipients - */ -function doSaveToFS(msg: PSTMessage, emailFolder: string, sender: string, recipients: string) { - try { - // save the msg as a txt file - const filename = emailFolder + msg.descriptorNodeId + '.txt'; - if (verbose) { - console.log('saving msg to ' + filename); - } - const fd = fs.openSync(filename, 'w'); - fs.writeSync(fd, msg.clientSubmitTime + '\r\n'); - fs.writeSync(fd, 'Type: ' + msg.messageClass + '\r\n'); - fs.writeSync(fd, 'From: ' + sender + '\r\n'); - fs.writeSync(fd, 'To: ' + recipients + '\r\n'); - fs.writeSync(fd, 'Subject: ' + msg.subject); - fs.writeSync(fd, msg.body); - fs.closeSync(fd); - } catch (err) { - console.error(err); - } - - // walk list of attachments and save to fs - for (let i = 0; i < msg.numberOfAttachments; i++) { - const attachment: PSTAttachment = msg.getAttachment(i); - if (attachment.filename) { - const filename = emailFolder + msg.descriptorNodeId + '-' + attachment.longFilename; - if (verbose) { - console.log('saving attachment to ' + filename); - } - try { - const fd = fs.openSync(filename, 'w'); - const attachmentStream = attachment.fileInputStream; - if (attachmentStream) { - const bufferSize = 8176; - const buffer = new Buffer(bufferSize); - let bytesRead; - do { - bytesRead = attachmentStream.read(buffer); - fs.writeSync(fd, buffer, 0, bytesRead); - } while (bytesRead == bufferSize); - fs.closeSync(fd); - } - } catch (err) { - console.error(err); - } - } - } -} - -/** - * Get the sender and display. - * @param {PSTMessage} email - * @returns {string} - */ -function getSender(email: PSTMessage): string { - - let sender = email.senderName; - if (sender !== email.senderEmailAddress) { - sender += ' (' + email.senderEmailAddress + ')'; - } - if (verbose && displaySender && email.messageClass === 'IPM.Note') { - console.log(getDepth(depth) + ' sender: ' + sender); - } - return sender; -} - -/** - * Get the recipients and display. - * @param {PSTMessage} email - * @returns {string} - */ -function getRecipients(email: PSTMessage): string { - // could walk recipients table, but be fast and cheap - return email.displayTo; -} - -/** - * Print a dot representing a message. - */ -function printDot() { - process.stdout.write('.'); - if (col++ > 100) { - console.log(''); - col = 0; - } -} - -/** - * Returns a string with visual indicattion of depth in tree. - * @param {number} depth - * @returns {string} - */ -function getDepth(depth: number): string { - let sdepth = ''; - if (col > 0) { - col = 0; - sdepth += '\n'; - } - for (let x = 0; x < depth - 1; x++) { - sdepth += ' | '; - } - sdepth += ' |- '; - return sdepth; -}