Skip to content

SpongeData-cz/gopst

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gopst

Golang binding for a libpst2 of a pseudo-forked project of libpst.

Installation

Requirements

libpst2 installation.

Usage

Creating an Pst

Creates a new Pst initialization and passes the path to the .pst file with the parameter.

Has to be deallocated with Destroy method after use.

pst := gopst.NewPst("./fixtures/sample.pst")
if pst.NumError != gopst.NO_ERROR {
    return errors.New(pst.LastError)
}

Export Configuration

Next, it is necessary to create the export configurator, according to which the subsequent Export is created.

This configurator is necessary for how the individual records will be unpacked.

Export configuration structure:

type ExportConf struct {
	Mode                 int
	ModeMH               int // A submode of MODE_SEPARATE
	ModeEX               int // A submode of MODE_SEPARATE
	ModeMSG              int // A submode of MODE_SEPARATE
	ModeThunder          int // A submode of MODE_RECURSE
	OutputMode           int
	ContactMode          int // Not used within the code
	DeletedMode          int // Not used within the code
	OutputTypeMode       int // Default to all. Not used within the code
	ContactModeSpecified int // Not used within the code
	Overwrite            int
	PreferUtf8           int
	SaveRtfBody          int // Unused
	FileNameLen          int // Enough room for MODE_SPEARATE file name
	AcceptableExtensions string
}

Settings options

Mode

  • MODE_NORMAL - Normal mode just creates mbox format files in the current directory. Each file is named the same as the folder's name that it represents.
  • MODE_KMAIL - KMail mode creates a directory structure suitable for being used directly by the KMail application.
  • MODE_RECURSE - Recurse mode creates a directory structure like the PST file. Each directory contains only one file which stores the emails in mboxrd format.
  • MODE_SEPARATE - Separate mode creates the same directory structure as recurse. The emails are stored in separate files, numbering from 1 upward. Attachments belonging to the emails are saved as email_no-filename (e.g. 1-samplefile.doc or 1-Attachment2.zip).

OutputMode

  • OUTPUT_NORMAL - Output Normal just prints the standard information about what is going on.
  • OUTPUT_QUIET - Output Quiet is provided so that only errors are printed.

ContactMode

  • CMODE_VCARD
  • CMODE_LIST

DeletedMode

  • DMODE_EXCLUDE
  • DMODE_INCLUDE

OutputTypeMode

  • OTMODE_EMAIL
  • OTMODE_APPOINTMENT
  • OTMODE_JOURNAL
  • OTMODE_CONTACT
  • OTMODE_ALL

Export Configuration default settings

func ExportConfDefault() ExportConf {
	return ExportConf{
		Mode:                 MODE_NORMAL,
		ModeMH:               0,
		ModeEX:               0,
		ModeMSG:              0,
		ModeThunder:          0,
		OutputMode:           OUTPUT_NORMAL,
		ContactMode:          CMODE_VCARD,
		DeletedMode:          DMODE_INCLUDE,
		OutputTypeMode:       OTMODE_ALL,
		ContactModeSpecified: 0,
		Overwrite:            0,
		PreferUtf8:           1,
		SaveRtfBody:          0,
		FileNameLen:          10,
		AcceptableExtensions: "",
	}
}

Creating and Export

Then we create a new initialization of the Export using the configurator.

Has to be deallocated with Destroy method after use.

export := gopst.NewExport(gopst.ExportConfDefault())
if export == nil {
    return errors.New("NewExport failed")
}

List

The next step is the List method. This method lists content of an pst in form of arrays.

Records must be destroyed by DestroyList call explicitly.

Alternatively, it is possible to destroy individual records using the Destroy function.

records := pst.List()

Extraction to file and renaming

Here comes the time for extraction. To extract, you need to iterate over the individual records and call the RecordToFile function on them individually with the export parameter passed.

Alternatively, Records can be renamed before extraction using the SetRecordRenaming method. The full path with the new name must be passed as a parameter.

for i, record := range records {
    newName := fmt.Sprintf("output_%d.eml", i)
    record.SetRecordRenaming(pathToExtract + newName)
    record.RecordToFile(export)
}

Errors in records

Next, it is a good idea to iterate through the records to see if any of them have errors.

This can be done, for example, with the following code:

for i, record := range records {
	if record.Err != NO_ERROR {
		fmt.Printf("Record %s has error %d\n", record.Name, record.Err)
	}
}

Destroy

Destroy Pst

First, the Pst must be destroyed using the Destroy function.

if err := pst.Destroy(); err != nil {
    return err
}

Destroy List

It is also necessary to destroy the list of records using the DestroyList function.

if err := gopst.DestroyList(records); err != nil {
    return err
}

Alternatively, it is possible to destroy individual records using the Destroy function.

if err := record.Destroy(); err != nil{
	return err
}

Destroy Export

The last thing to do is to destroy the export also using the Destroy function.

if err := export.Destroy(); err != nil {
    return err
}

Errors

Different types of errors are defined by constants.

const (
    NO_ERROR = iota
    ERROR_NOT_UNIQUE_MSG_STORE
    ERROR_ROOT_NOT_FOUND
    ERROR_OPEN
    ERROR_INDEX_LOAD
    ERROR_UNKNOWN_RECORD
)

/*
Record to file errors.
*/
const (
	PST_MESSAGE_ERROR_FILE_ERROR = iota + 1
	PST_MESSAGE_ERROR_UNSUPPORTED_PARAM
)

Example

import (
	"errors"
	"fmt"

	"github.com/SpongeData-cz/gopst"
)

func example() error {
	path := "./fixtures/"

	// Creates a new Pst
	pst := gopst.NewPst(path + "sample.pst")
	if pst.NumError != gopst.NO_ERROR {
		return fmt.Errorf("NewPst failed with error %d", pst.NumError)
	}

	// Creates a new Export
	export := gopst.NewExport(gopst.ExportConfDefault())
	if export == nil {
		pst.Destroy()
		return errors.New("NewExport failed")
	}

	// Make slice of Records
	records := pst.List()

	for i, record := range records {
		// Optional Records rename
		record.SetRecordRenaming(path + fmt.Sprintf("out/output_%d.eml", i))

		// Record extraction
		record.RecordToFile(export)
	}

	// Inspection of per-Record errors
	for _, record := range records {
		if record.Err != gopst.NO_ERROR {
			fmt.Printf("WARNING %s, ERROR WITH NUMBER: %d\n", record.Name, record.Err)
		}
	}

	// Correct Pst removal
	if err := pst.Destroy(); err != nil {
		export.Destroy()
		gopst.DestroyList(records)
		return err
	}

	// Correct Records removal
	if err := gopst.DestroyList(records); err != nil {
		export.Destroy()
		return err
	}

	// Correct Export removal
	if err := export.Destroy(); err != nil {
		return err
	}

	return nil
}

About

Libpst tools (pst parsing) integration.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages