How the Grinn was Saved

This page should eventually be fleshed out with the enite narrative of how the Evil Grinn files were preserved.

For now, all that is here is the Perl script that was used to convert the old WWIV files to HTML for the message archives.

How the Messages Were Converted to HTML

Without access to the WWIV source code, I had to figure out the format of the files just by looking at them in a hexdump. My understanding is still less than perfect. This puts some limitations on the capabilities of the Perl script.

The format of WWIV's data files, at least what I figured out

The master list of sub-boards is data\subs.dat. This file is made up of fixed-length records. The records start right at the beginning of the file. Each record contains the friendly name of the sub and its actual internal name as null-terminated strings, followed by some data that I couldn't decipher. I assume that in the real WWIV source these fixed-length records are read directly into C structs. The struct probably looks something like this:

struct subs_dat_record {
   char friendly_name[41];
   char real_name[9];
   char unknown[13];
};

The message titles (but not the messages themselves) are stored in data\subname.sub, where subname is the name found from subs.dat. The first 100 bytes of this file appear to be garbage. The records are 100 bytes long. WWIV only allows message titles to be 60 characters long, so 39 bytes are being used for some unknown purpose. Again, the title is null-terminated.

struct title_record {
   char title[61];
   char unknown[39];
};

The messages for each sub are stored in msgs\subname.dat, one for each sub. All messages begin at byte offsets which are multiples of 512, starting at 4608 (or 0x1200, which is a lot easier to remember). The end of a message is indicated by a CTRL-Z (0x1A) character. The message text contains "header" lines which indicate the sender and the date of the message, but not the title.

What I Could Not Figure Out

I was not able to figure out how the BBS indexes and sorts messages, as they seemed to be in no particular order, and if a single message was longer than 512 bytes the blocks that contained it weren't neccessarily contigous. Possibly this information is stored the message-title structure, but I couldn't find it.

Fortunately after running some of the available "sub defragging" tools, the messages were all neatly arranged contiguous and in the correct order (the order in which they were posted).

Because the titles and the actual message bodies are sorted in the same order, you can just read through both the .sub file and the .dat file and collate the two together. There are still some places where this algorithm gets thrown off, and messages end up with the wrong title! Based on which subs this happens to, it seems to have something to do with one or more of the following conditions:

Another thing I haven't quite figured out is email. Email appears to mostly be stored in the same manner as normal messages, but I can't figure out how to tell who the email was sent to.

Here is the actual Perl script.

1