Extension development
Request for .PMM File Format

I have opened a thread at http://community.pmail.com/forums/thread/6239.aspx in the Technical Support section as a bug report/request for information.

Hopefully David may be willing/able to shed some light on this?
 

<p>I have opened a thread at http://community.pmail.com/forums/thread/6239.aspx in the Technical Support section as a bug report/request for information. </p><p>Hopefully David may be willing/able to shed some light on this?  </p>

Where can I find documentation on directly accessing/parsing a .PMM file? It seems to consist of messages prefixed with additional flags?

 

<P>Where can I find documentation on directly accessing/parsing a .PMM file? It seems to consist of messages prefixed with additional flags?</P> <P mce_keep="true"> </P>

This information is not to be spread widely. Mail me directly (include reason why) and I can try to see what I have stored over the years.

Han.


<p>This information is not to be spread widely. Mail me directly (include reason why) and I can try to see what I have stored over the years. </p><p>Han.</p><p> </p>

-- Han van den Bogaerde - support@vandenbogaerde.net Member of Pegasus Mail Support Group. My own Pegasus Mail related web information: http://www.vandenbogaerde.net/pegasusmail/

[quote user="Han v.d. Bogaerde"]

This information is not to be spread widely.

[/quote]

Han, thank you for this, but I think these days the requirement for secrecy is really a pretty laughable facet of the older, more arrogant David. The modern, less concerned David really doesn't mind if this information makes its way into the public domain - indeed, I think there's a real merit in having this type of thing in the FAQs section here.

It's quite possible that you actually have considerably better resources for this type of documentation than I do at the moment, so if you can put something together, please feel free to make it available. If you haven't, let me know and I'll see what I can dig out: I know I wrote some basic descriptions of the various formats a number of years ago, and I can probably still find them with a little effort.

Cheers!

-- David --

[quote user="Han v.d. Bogaerde"]<p>This information is not to be spread widely. </p>[/quote] Han, thank you for this, but I think these days the requirement for secrecy is really a pretty laughable facet of the older, more arrogant David. The modern, less concerned David really doesn't mind if this information makes its way into the public domain - indeed, I think there's a real merit in having this type of thing in the FAQs section here. It's quite possible that you actually have considerably better resources for this type of documentation than I do at the moment, so if you can put something together, please feel free to make it available. If you haven't, let me know and I'll see what I can dig out: I know I wrote some basic descriptions of the various formats a number of years ago, and I can probably still find them with a little effort. Cheers! -- David --

David, this is the last I've gotten from the old Admin manual but I know that there have been changes.


Folders:

A Pegasus Mail 2.2 folder consists of two files. The master file has the extension .PMM: it has a 128-byte header of which the first 50 bytes are the long name of the folder, the remainder being reserved. Following the header is the text of all the messages in the folder, separated by ^Z characters (ASCII 26). Some of the messages stored in the folder may in fact be deleted  there is no way of determining this without consulting the record matching the message in the .PMI index file for the folder.

The other file has the extension .PMI, and consists of a
representation of the message using a structure called an IMESSAGE, shown below in its C language definition (note that all integer values in the file are stored in Intel word order  Pegasus Mail for the Macintosh does whatever conversion is necessary for its Motorola processor as it loads each entry from the index):

typedef struct
{
unsigned long flags;
unsigned long fpos; /* Offset in master file */
WORD msg_number; /* Msg ordinal position */
char fname; /* Unused in folders */
char from [30]; /* Sender of message */
char subject [36]; /* Guess what this is */
char date [20]; /* Reduced form of date */
long mtime; /* See below */
long fsize; /* Bytes in this message */
} IMESSAGE;

flags is a bitmap of message characteristics, using the following values:

0x1 The message has Pegasus Mail-style attachments
0x2 The message is a uuencoded file transmission
0x4 The message is encrypted
0x80 The message has been read
0x2000 Sender requests confirmation of reading
0x20000L The message is a copy to self
0x40000L The message has been deleted
0x80000L The message is in a MIME transmission format
0x100000L A reply has been sent for this message
0x200000L The message has been forwarded to another user
0x400000L The message is urgent (never seen in folders)
0x800000L The message contains BinHex-encoded enclosures
0x1000000L The message originates from an MHS system
0x2000000L The message originates from an SMTP system.
0x4000000L The message has annotations.
0x8000000L The message contains enclosures

All other values are reserved - do not use them.

The mtime field is a crude calculation of the number of seconds since Jan 1 1990, used only for sorting purposes. It is not intended to be accurate merely "near enough".

The fsize field can be larger than the actual size of the message, but in no circumstance should it be less - this will cause Pegasus Mail to crash.

David, this is the last I've gotten from the old Admin manual but I know that there have been changes. Folders: A Pegasus Mail 2.2 folder consists of two files. The master file has the extension .PMM: it has a 128-byte header of which the first 50 bytes are the long name of the folder, the remainder being reserved. Following the header is the text of all the messages in the folder, separated by ^Z characters (ASCII 26). Some of the messages stored in the folder may in fact be deleted  there is no way of determining this without consulting the record matching the message in the .PMI index file for the folder. The other file has the extension .PMI, and consists of a representation of the message using a structure called an IMESSAGE, shown below in its C language definition (note that all integer values in the file are stored in Intel word order  Pegasus Mail for the Macintosh does whatever conversion is necessary for its Motorola processor as it loads each entry from the index): typedef struct { unsigned long flags; unsigned long fpos; /* Offset in master file */ WORD msg_number; /* Msg ordinal position */ char fname; /* Unused in folders */ char from [30]; /* Sender of message */ char subject [36]; /* Guess what this is */ char date [20]; /* Reduced form of date */ long mtime; /* See below */ long fsize; /* Bytes in this message */ } IMESSAGE; flags is a bitmap of message characteristics, using the following values: 0x1 The message has Pegasus Mail-style attachments 0x2 The message is a uuencoded file transmission 0x4 The message is encrypted 0x80 The message has been read 0x2000 Sender requests confirmation of reading 0x20000L The message is a copy to self 0x40000L The message has been deleted 0x80000L The message is in a MIME transmission format 0x100000L A reply has been sent for this message 0x200000L The message has been forwarded to another user 0x400000L The message is urgent (never seen in folders) 0x800000L The message contains BinHex-encoded enclosures 0x1000000L The message originates from an MHS system 0x2000000L The message originates from an SMTP system. 0x4000000L The message has annotations. 0x8000000L The message contains enclosures All other values are reserved - do not use them. The mtime field is a crude calculation of the number of seconds since Jan 1 1990, used only for sorting purposes. It is not intended to be accurate merely "near enough". The fsize field can be larger than the actual size of the message, but in no circumstance should it be less - this will cause Pegasus Mail to crash.

Thanks guys, these are very interesting information. Just a few additional queries:

  • What does the "mtime" field stands for? The equivalent of date field or something else?
  • I don't suppose a programming API is available for people who want to use the "official" way to read/write PMM files as well as navigating the folder hierarchy rather than asking them to parse *.PMM and HIERARCH.PM files themselves? [:)]

 

 

<P>Thanks guys, these are very interesting information. Just a few additional queries:</P> <UL> <LI>What does the "mtime" field stands for? The equivalent of date field or something else?</LI> <LI>I don't suppose a programming API is available for people who want to use the "official" way to read/write PMM files as well as navigating the folder hierarchy rather than asking them to parse *.PMM and HIERARCH.PM files themselves? [:)]</LI></UL> <P mce_keep="true"> </P> <P mce_keep="true"> </P>

[quote user="pmuser"]

Thanks guys, these are very interesting information. Just a few additional queries:

  • What does the "mtime" field stands for? The equivalent of date field or something else?

[/quote]


"mtime" is a crude hash value based on the date which is used only when
sorting the folder. The code which calculates this value is as follows:

    long extract_time (char *s)
       {
       int year, mon, day, hour, min, i;
       char monthstr [10], *base;
       long l;

       /*  Extract a date in RFC-822 date format, and:
       **  i:   Sprintf() it into a consistent format for display.
       **  ii:  Calculate a sequence value. The sequence value is
       **       used for sorting by date, and is crudely calculated.
       **       It is very nominally the number of minutes since
       **       Jan 1 1990, but in fact it ends up being nothing like
       **       this. This doesn't matter provided the sequence it
       **       produces is correct (which it is).
       */

       if (s [3] == ',')
          base = s + 4;
       else
          base = s;

       if (sscanf (base, "%d %s %d %d:%d", &day, monthstr, &year,
       &hour, &min) != 5)
          return 0L;

       for (mon = 0, i = 0; i < 12; i ++)
          if (stricmp (monthstr, months ) == 0)
             {
             mon = i;
             break;
             }

       if (year > 1900) year -= 1900;
       l = (year - 90) * 535680L;          /* 12 * 31 * 1440 (months) */
       l += (mon * 44640L);                /* 31 * 1440 (days)        */
       l += (day * 1440L);                 /* 60 * 24 hours           */
       l += (hour * 60L);                  /* 60 minutes              */
       l += min;

       sprintf (s, "%2d %s %02d %2d:%02d", day, monthstr, year, hour, min);
       return l;
       }
 

 

[quote user=&quot;pmuser&quot;]&lt;p&gt;Thanks guys, these are very interesting information. Just a few additional queries:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;What does the &quot;mtime&quot; field stands for? The equivalent of date field&amp;nbsp;or something else?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; [/quote]&lt;/p&gt;&lt;p&gt; &quot;mtime&quot; is a crude hash value based on the date which is used only when sorting the folder. The code which calculates this value is as follows: &amp;nbsp;&amp;nbsp;&amp;nbsp; long extract_time (char *s) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int year, mon, day, hour, min, i; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char monthstr [10], *base; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; long l; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&amp;nbsp; Extract a date in RFC-822 date format, and: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp; i:&amp;nbsp;&amp;nbsp; Sprintf() it into a consistent format for display. &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp; ii:&amp;nbsp; Calculate a sequence value. The sequence value is &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; used for sorting by date, and is crudely calculated. &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; It is very nominally the number of minutes since &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Jan 1 1990, but in fact it ends up being nothing like &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this. This doesn&#039;t matter provided the sequence it &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; produces is correct (which it is). &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s [3] == &#039;,&#039;) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base = s + 4; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base = s; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (sscanf (base, &quot;%d %s %d %d:%d&quot;, &amp;amp;day, monthstr, &amp;amp;year, &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;hour, &amp;amp;min) != 5) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0L; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (mon = 0, i = 0; i &amp;lt; 12; i ++) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (stricmp (monthstr, months [i]) == 0) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mon = i; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (year &amp;gt; 1900) year -= 1900; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l = (year - 90) * 535680L;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 12 * 31 * 1440 (months) */ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l += (mon * 44640L);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 31 * 1440 (days)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l += (day * 1440L);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 60 * 24 hours&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l += (hour * 60L);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 60 minutes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l += min; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sprintf (s, &quot;%2d %s %02d %2d:%02d&quot;, day, monthstr, year, hour, min); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return l; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;

-- Han van den Bogaerde - support@vandenbogaerde.net Member of Pegasus Mail Support Group. My own Pegasus Mail related web information: http://www.vandenbogaerde.net/pegasusmail/

Thank you for posting this.  This is, however, exactly what is in a file called UNIX2PM.H which is part of an archive that purports to try to convert MBOX to Pegasus mail.  Your exposition above is wrong, also.  The fname field is a char [14], not a single char.

 Also, upon viewing a hexdump of a PMI file, there is a  4 character (probably unsigned long?) value at the end of the date field, making the length of the date field 16 instead of 20.

 David, could you please clarify?

 
Also, and I maybe should be posting this in another new thread, but I have the feeling that these fields are related, there is a problem with annotations.  The old style of annotations had an "A" as the first letter and were able to be easily found if one knew the name of the PMM file.  Now, the annotation filenames are 16 byte hash values which have no obvious connection to the message they pertain to.

The old annotations are lost.  This is a bug. If there is any documentation about what to do about this to convert the annotations to the new format, please show me.
 

&lt;p&gt;Thank you for posting this.&amp;nbsp; This is, however, exactly what is in a file called UNIX2PM.H which is part of an archive that purports to try to convert MBOX to Pegasus mail.&amp;nbsp; Your exposition above is wrong, also.&amp;nbsp; The fname field is a char [14], not a single char.&lt;/p&gt;&lt;p&gt;&amp;nbsp;Also, upon viewing a hexdump of a PMI file, there is a&amp;nbsp; 4 character (probably unsigned long?) value at the end of the date field, making the length of the date field 16 instead of 20.&lt;/p&gt;&lt;p&gt;&amp;nbsp;David, could you please clarify?&lt;/p&gt;&lt;p&gt;&amp;nbsp; Also, and I maybe should be posting this in another new thread, but I have the feeling that these fields are related, there is a problem with annotations.&amp;nbsp; The old style of annotations had an &quot;A&quot; as the first letter and were able to be easily found if one knew the name of the PMM file.&amp;nbsp; Now, the annotation filenames are 16 byte hash values which have no obvious connection to the message they pertain to.&lt;/p&gt;&lt;p&gt;The old annotations are lost.&amp;nbsp; This is a bug. If there is any documentation about what to do about this to convert the annotations to the new format, please show me. &amp;nbsp;&lt;/p&gt;

Here is the latest V2 format for the PMI file:

 The index file:  the .PMI file contains a preparsed version of each
message in the file represented in a flat structure. The file is not
sorted in any way and has no header component. The structure used in the
index file is as follows:

typedef unsigned long ULONG
typedef unsigned short USHORT
typedef short INT_16
typedef unsigned char UCHAR

typedef struct
   {
   ULONG flags;          /* (*See details below)
   ULONG fpos;           /* Offset within 2.2 folder to this message */
   USHORT msg_number;    /* Ordinal position of this IMESSAGE in index */
   char fname [14];      /* Name of file containing the message */
   char from [30];       /* The sender of the message */
   char subject [36];    /* Can you guess what this is? */
   char date [16];       /* The time and date the message was despatched */
   INT_16 unused;        /* Not currently used. */
   UCHAR colour;         /* Display colour for this entry */
   char unused_2;        /* Not currently used */
   long mtime;           /* Binary version of message date for sorting */
   long fsize;           /* DOS size of this message (*The ^z separating
                            messages is not a part of this count) */
   } IMESSAGE;

As with the master file headers, Intel word order is used.

The "flags" field is a bitmap which contains information about the
message; the following bit values are possible:

#define FILE_MAILED            1   // IMESSAGE flag indicates mailed file
/* (*FILE_MAILED is set/cleared by "has local-style attachments" checkbox) */
#define UUENCODED              2   // "   "   "   "   "   "   uuencoding
#define ENCRYPTED              4   // "   "   "   "   "   "   encryption
#define DIGEST                 8   // (*) The message is a digest
#define EXPIRED             0x10   // The message is past its expiry date
#define FILE_ASCII          0x20   // (#) Attachment flag indicates ASCII file
#define HAS_BEEN_READ       0x80   // Indicates that an IMESSAGE has been read
#define HAS_ALT_VERS       0x100   // (*) Message has alternative versions
#define HAS_HTML           0x200   // (*) Message contains HTML data
#define CONFIRMATION      0x2000   // (#) Sender wants confirmation of reading
#define CONTENT_CTRL      0x4000   // (*) Message has undergone CC Processing
#define COPYSELF         0x20000L  // The message is a copy to self
#define DELETED          0x40000L  // (#) The message has been deleted.
#define MIME             0x80000L  // The message is a MIME transmission
#define REPLIED         0x100000L  // The message has been replied to.
#define FORWARDED       0x200000L  // The message has been forwarded.
#define URGENT          0x400000L  // The message is urgent/high priority.
#define BINHEX          0x800000L  // The message is a BinHex file
#define IS_MHS         0x1000000L  // The message originated from MHS
#define IS_SMTP        0x2000000L  // The message originated via SMTP
#define IS_ANNOTATED   0x4000000L  // The message has an annotation
#define ENCLOSURE      0x8000000L  // The message has enclosures
#define HIGHLIGHTED   0x10000000L  // The message has transient significance
#define MIME_MULTI    0x20000000L  // The message is in MIME Multipart format
#define TEXT_ENRICHED 0x40000000L  // The message is in "text/enriched" format
#define READ_ONLY     0x80000000L  // The message may not be deleted

All unused bit values are strictly reserved - you must not attempt to
set any other bit in the mask.

"fpos" should represent the offset of the first byte of the message in
the master file (Intel order). (*Relative to zero)

"msg_number" should be an index value into the index file at which this
IMESSAGE structure can be found. It is used as a quick way of calculating
where the IMESSAGE is in case it needs to be updated. (*Relative to zero)

"fname" is used in new mail to contain the filename of the message. For
mail in folders it can have any value so long as it is unique (usually it
is best to leave it as the name of the original new mail file).

"from", "subject" and "date" contain excerpted versions of these fields
from the message, and are used only for screen display in the browser.
You should NEVER attempt to generate replies based on these fields. In
the event that they contain high-bit characters, these fields will
contain them in the IBM-437 character set: Macintosh and Windows clients
are responsible for ensuring that characters are stored in this format as
required.

 The mtime posting in this thread is the latest  version.

 

&lt;p&gt;Here is the latest V2 format for the PMI file:&lt;/p&gt;&lt;p&gt;&amp;nbsp;The index file:&amp;nbsp; the .PMI file contains a preparsed version of each message in the file represented in a flat structure. The file is not sorted in any way and has no header component. The structure used in the index file is as follows: typedef unsigned long ULONG typedef unsigned short USHORT typedef short INT_16 typedef unsigned char UCHAR typedef struct &amp;nbsp;&amp;nbsp; { &amp;nbsp;&amp;nbsp; ULONG flags;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* (*See details below) &amp;nbsp;&amp;nbsp; ULONG fpos;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Offset within 2.2 folder to this message */ &amp;nbsp;&amp;nbsp; USHORT msg_number;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Ordinal position of this IMESSAGE in index */ &amp;nbsp;&amp;nbsp; char fname [14];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Name of file containing the message */ &amp;nbsp;&amp;nbsp; char from [30];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* The sender of the message */ &amp;nbsp;&amp;nbsp; char subject [36];&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Can you guess what this is? */ &amp;nbsp;&amp;nbsp; char date [16];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* The time and date the message was despatched */ &amp;nbsp;&amp;nbsp; INT_16 unused;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Not currently used. */ &amp;nbsp;&amp;nbsp; UCHAR colour;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Display colour for this entry */ &amp;nbsp;&amp;nbsp; char unused_2;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Not currently used */ &amp;nbsp;&amp;nbsp; long mtime;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Binary version of message date for sorting */ &amp;nbsp;&amp;nbsp; long fsize;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* DOS size of this message (*The ^z separating &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; messages is not a part of this count) */ &amp;nbsp;&amp;nbsp; } IMESSAGE; As with the master file headers, Intel word order is used. The &quot;flags&quot; field is a bitmap which contains information about the message; the following bit values are possible: #define FILE_MAILED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp; // IMESSAGE flag indicates mailed file /* (*FILE_MAILED is set/cleared by &quot;has local-style attachments&quot; checkbox) */ #define UUENCODED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp; // &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; uuencoding #define ENCRYPTED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp; // &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; &quot;&amp;nbsp;&amp;nbsp; encryption #define DIGEST&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp; // (*) The message is a digest #define EXPIRED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x10&amp;nbsp;&amp;nbsp; // The message is past its expiry date #define FILE_ASCII&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x20&amp;nbsp;&amp;nbsp; // (#) Attachment flag indicates ASCII file #define HAS_BEEN_READ&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x80&amp;nbsp;&amp;nbsp; // Indicates that an IMESSAGE has been read #define HAS_ALT_VERS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x100&amp;nbsp;&amp;nbsp; // (*) Message has alternative versions #define HAS_HTML&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x200&amp;nbsp;&amp;nbsp; // (*) Message contains HTML data #define CONFIRMATION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x2000&amp;nbsp;&amp;nbsp; // (#) Sender wants confirmation of reading #define CONTENT_CTRL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4000&amp;nbsp;&amp;nbsp; // (*) Message has undergone CC Processing #define COPYSELF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x20000L&amp;nbsp; // The message is a copy to self #define DELETED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x40000L&amp;nbsp; // (#) The message has been deleted. #define MIME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x80000L&amp;nbsp; // The message is a MIME transmission #define REPLIED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x100000L&amp;nbsp; // The message has been replied to. #define FORWARDED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x200000L&amp;nbsp; // The message has been forwarded. #define URGENT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x400000L&amp;nbsp; // The message is urgent/high priority. #define BINHEX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x800000L&amp;nbsp; // The message is a BinHex file #define IS_MHS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1000000L&amp;nbsp; // The message originated from MHS #define IS_SMTP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x2000000L&amp;nbsp; // The message originated via SMTP #define IS_ANNOTATED&amp;nbsp;&amp;nbsp; 0x4000000L&amp;nbsp; // The message has an annotation #define ENCLOSURE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x8000000L&amp;nbsp; // The message has enclosures #define HIGHLIGHTED&amp;nbsp;&amp;nbsp; 0x10000000L&amp;nbsp; // The message has transient significance #define MIME_MULTI&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x20000000L&amp;nbsp; // The message is in MIME Multipart format #define TEXT_ENRICHED 0x40000000L&amp;nbsp; // The message is in &quot;text/enriched&quot; format #define READ_ONLY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x80000000L&amp;nbsp; // The message may not be deleted All unused bit values are strictly reserved - you must not attempt to set any other bit in the mask. &quot;fpos&quot; should represent the offset of the first byte of the message in the master file (Intel order). (*Relative to zero) &quot;msg_number&quot; should be an index value into the index file at which this IMESSAGE structure can be found. It is used as a quick way of calculating where the IMESSAGE is in case it needs to be updated. (*Relative to zero) &quot;fname&quot; is used in new mail to contain the filename of the message. For mail in folders it can have any value so long as it is unique (usually it is best to leave it as the name of the original new mail file). &quot;from&quot;, &quot;subject&quot; and &quot;date&quot; contain excerpted versions of these fields from the message, and are used only for screen display in the browser. You should NEVER attempt to generate replies based on these fields. In the event that they contain high-bit characters, these fields will contain them in the IBM-437 character set: Macintosh and Windows clients are responsible for ensuring that characters are stored in this format as required. &amp;nbsp;The mtime posting in this thread is the latest&amp;nbsp; version.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;

-- Han van den Bogaerde - support@vandenbogaerde.net Member of Pegasus Mail Support Group. My own Pegasus Mail related web information: http://www.vandenbogaerde.net/pegasusmail/

Ah, thank you (Dank U) Han.... exactly what I needed.

 

Could you clarify the annotation issue?  Should I move that to another thread? 

 

I would like to convert the old annotations to the new format so they can be seen in the message as before, and I also would like a way to find the annotation file given the message in the PMI/PMM file.  If you want I can email you directly if this is a secret for any reason. 

&lt;p&gt;Ah, thank you (Dank U) Han.... exactly what I needed.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Could you clarify the annotation issue?&amp;nbsp; Should I move that to another thread?&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;I would like to convert the old annotations to the new format so they can be seen in the message as before, and I also would like a way to find the annotation file given the message in the PMI/PMM file.&amp;nbsp; If you want I can email you directly if this is a secret for any reason.&amp;nbsp;&lt;/p&gt;

[quote user="Robert_Lema"] 

Could you clarify the annotation issue?  Should I move that to another thread? I would like to convert the old annotations to the new format so they can be seen in the message as before, and I also would like a way to find the annotation file given the message in the PMI/PMM file.  If you want I can email you directly if this is a secret for any reason. 

[/quote]

I really have no idea how the relation between messages and annotations is kept? Sorry.

 

[quote user=&quot;Robert_Lema&quot;]&amp;nbsp;&lt;p&gt;Could you clarify the annotation issue?&amp;nbsp; Should I move that to another thread? I would like to convert the old annotations to the new format so they can be seen in the message as before, and I also would like a way to find the annotation file given the message in the PMI/PMM file.&amp;nbsp; If you want I can email you directly if this is a secret for any reason.&amp;nbsp;&lt;/p&gt;&lt;p&gt;[/quote]&lt;/p&gt;&lt;p&gt;I really have no idea how the relation between messages and annotations is kept? Sorry.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;

-- Han van den Bogaerde - support@vandenbogaerde.net Member of Pegasus Mail Support Group. My own Pegasus Mail related web information: http://www.vandenbogaerde.net/pegasusmail/

live preview
enter atleast 10 characters
WARNING: You mentioned %MENTIONS%, but they cannot see this message and will not be notified
Saving...
Saved
With selected deselect posts show selected posts
All posts under this topic will be deleted ?
Pending draft ... Click to resume editing
Discard draft