PBBS16 Documentation

PBBS JAM API

As mentioned in the product overview, I took the published JAMmb Pascal source from Joaquim Homrighausen which was for DOS 16bit compilers and revised the design to work as a built-in 32bit/64bit Object in the Modern Pascal Language (MPL). Originally, I looked at using MKMSG v1.06 from Mark May (one of my OOP mentors in the early Turbo Pascal days). However, I had seen posts of different bugs in the JAM implementation and I did not want to risk introducing bugs to this project. Looking around on my old Softnet CD, I found where we had a copy of the code from Joaquim Homrighausen. As I started rewriting the code, so I could absorb it to memory, I found a few potential quirks. So, I went on to SourceForge and reviewed the Husky Fidonet Project's JAMmb API source. I found a change they made to the main header structure (adding a field to track the highest message number found by the tosser the last time it did a scan, most packages do this in their own file instead of modifying a published API). So, I incorporated it into my rewrite just to make sure anything Modern Pascal does is compatible with Husky, and since this uses the reserved 1000 bytes of null - it will not affect/effect older software either.

DXJAM is the Object defined in the Modern Pascal Language. Some of the changes I made are:
  1. I made a new DOS forward File I/O object - made to handle File I/O more efficiently on DOS, and provide a common set of methods for other operating systems supported by the MPL.
  2. I extended the internal API status codes, so a routine that needs access to the message base in a certain state can return that the files are open, but you forgot to lock them (as an example).
  3. I extended the Message status bits to incorporate flags for other implementations besides Fidonet. Not a message can be flagged as originating on the NNTP server, imported from the email server, etc.
  4. Many new header subfields were introduced to handle the evolution of Fidonet since the source I used was written, along with subfields to denote aspects of NNTP and SMTP headers.
  5. As previously mentioned, I added HighWater:Longint to the HDR Info structure, and modified Reserved from 1000 to 996 of null.
  6. I introduced a couple of fields to the Internal global to track IsDirty (the message header needs to be flushed to disk), LastLRDNum (the highest record number in the LastRead file for this message base), and a couple of other tricks to optimize the LastRead update(s) and Reading and Parsing the message body.
  7. Message Navigation follows the methods commonly found in a TDataset (First, Next, Prior, Last, BOF, EOF).
  8. I introduced new methods (extensions) to simplify creating a new message (for a tosser or a BBS).
  9. I simplified how to put an existing message into edit state - that optimizes for header changes only (like incrementing the times read counter).
  10. I implemented a quick Find(ToUserName) and FindNext(ToUserName) great for "New Mail" for a user from a message base that has a global set of posters (like Fidonet).
  11. OpenMB has been modified to create missing files. I found that on certain occasions the Linux OS would report a successful CreateMB, however, the zero-byte file(s) were missing if you didn't actually lock/unlock and close the messages. This could happen when the tosser would receive a corrupt PKT file. (This has been fixed in the tosser and in the DXJAM API).
  12. CreateMB has been modified that if creating any of the 2nd, 3rd or 4th files fails, all of the files successfully created are deleted, and CreateMB reports the error.
There are many more improvements, and a couple of logic issues that have been addressed before DXJAM API was incorporated into the Modern Pascal Language. On our test system, the DXJAM API has been pushed to over 680 messages written in a second. And this includes opening and closing the message API as the message base(s) are changed. This included 231 different message bases, with over 110,000 total messages.