Golang binding for a libpst2 of a pseudo-forked project of libpst.
libpst2 installation.
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)
}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
}- 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).
- 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.
- CMODE_VCARD
- CMODE_LIST
- DMODE_EXCLUDE
- DMODE_INCLUDE
- OTMODE_EMAIL
- OTMODE_APPOINTMENT
- OTMODE_JOURNAL
- OTMODE_CONTACT
- OTMODE_ALL
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: "",
}
}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")
}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()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)
}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)
}
}First, the Pst must be destroyed using the Destroy function.
if err := pst.Destroy(); err != nil {
return err
}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
}The last thing to do is to destroy the export also using the Destroy function.
if err := export.Destroy(); err != nil {
return err
}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
)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
}