




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 1

      This file contains a list of all structured files that Mutant creates
  via an editor or during runtime.  You should refer to the main Mutant
  documentation for further information  on some files.  This applies to
  version 1.1 Mutant and may or may not apply to future versions of the
  program.  I thought in .69 that I had fairly defined everything I wanted,
  but in .72 everything is different except the menus.

      Mutant was written with Turbo C++ v1.0.  I compiled it with word
  alignment on.  This means that all non-character data (ints,longs, etc.) lie
  on an even boundary and the structure size is an even number.  Therefore,
  the size you may think a structure is, may not be the correct size. For
  example,

       struct example {
           char data[5];
           unsigned num;
       };

  has a size of 8 bytes since Turbo C inserts an extra byte after the data
  field to make num fall on an even address.  I also made use of C's bitfields
  which can be decoded by other programs as follows:

      struct bit_examp {            struct nonbit_examp {
         int num;                          int num;
         unsigned bitf1:1;                 unsigned bitf;
         unsigned bitf2:1;          };
         unsigned bitf3:1;
         unsigned bitf4:2;
      };

      bit 0 of bitf would be bitf1
      bit 1 of bitf would be bitf2
      bit 2 of bitf would be bitf3
      bits 3&4 of bitf would be bitf4

  There is a bug in Turbo C++ v1.0 with its bitfields.  I have tried to work
  around this bug.  The bug involves the last byte of bitfields would overlap
  the next byte of data.  Causing a change to the bitfield to change the next
  data element, and the change of data element affecting one or more
  bitfields.  A very annoying bug, and with this version I have moved all
  bitfields to the end of the structures.

  I have given the size of structures, so you should check your size and make
  sure they match, if not you have an alignment problem.

  Finally, if you don't know C, array elements are numbered 0 to n-1 where n
  is the element given.  Also, strings in C are just an array of characters
  with the string ending with an 0.  Also, time_t is a C directive for a
  signed 32-bit number representing the number of seconds since midnight on




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 2

  January 1, 1970. Also, TC's default size for unsigned and int is 16-bits.
  Now on to the structures:

  System configuration (usually CONFIG.DAT) is defined with the following
  structure:

  struct sys_config { // Size:4096
    char sysop_name[36];
    char message_path[64];             // pathname for message bases 
    char menus_path[64];               // pathname where screens are stored 
    char xfer_path[64];                /* Path where file transfer info is
                                          stored. */ 
    char syst_path[64];                /* System files path 
    char nodelist_path[64];            // Path to the nodelist
    char temp_path[64];                // Temporary storage directory 
    char nodedir[64];                  // Where to store node.* and *.cht 
    char attachdir[64];                // "root" directory for file attaches 
    char remote_upload[82];            // SACS to use upload file in editors 
    char cosysop_sacs[82];             // SACS to be a cosysop 
    char colors[30];                   /* Colors in IBM screen attribute byte
                                          form */
    int  input_time_out;               /* Inactivity time in minutes until
                                          board hangs up */
    char hidden_input;                 // hidden input char for passwords
    char sysop_hang[51];               /* Default message when sysop presses
                                          F5 to hang-up user. */ 
    char boardname[52];                // Name of the BBS 
    char termprog[81];                 // Filespec for 'T' on WFC 
    char origin_line[51];              // Default origin line 
    int zone,net,node,point;           // Default Fido address 
    char hotkeys[8][81];               // F6&F7 hot-keys 
    char init[3][46];                  // Modem initialization strings
    unsigned init_pause;               // Init delay in milliseconds
    char hang_up[31];                  // Modem Hang-up string 
    char answer[31];                   // Modem answer string 
    char offhook[31];                  // Off-hook string 
    char fs_chat[2][6];                // Full screen chat control strings
    char drives[10];                   // WFC drive letters
    char name_length;                  // reserved
    char munused[2];                   // Unused space 
    int  vmode;                        // Video mode
    int  int_recv,int_tran;            // Receive and Transmit buffer sizes
    char reset[31];                    /* Reset string, used when Mutant is
                                          quit */
    char ok[31];                       // OK result, usually "OK" 
    char rc[24][41];                   /* Results codes */
    char ring[30];                     // Ring result 
    unsigned long bauds[24];           /* Associated bauds with result codes
                                          */




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 3

    unsigned com_port;                 // Com_port COM1=0 for FOSSIL use 
    unsigned long baud_rate;           // Baud rate Max=115200
    unsigned long max_tb;              /* Maximum time in time bank in seconds
                                          */
    char reserved[68];
    int screen_blank;                  // Time before blanking WFC screen 
    int pass_tries;                    /* Number of tries at password,
                                          0-infinite */
    int disk_free;                     // Min disk free to write in K 
    int pass_area;                     /* Area to post bad password Msg, -1
                                          =ignore */
    int pass_days;                     /* Number of days before users must
                                          change password, 0-never */
    int reinit_time;                   /* inactive time before re-initting
                                          modem */
    unsigned pc_delay;                 // After Connection delay
    char replyhdr[60];                 // Message reply header
    char quote[14];                    // Quote string
    char page_path[64];                // Page Sound path
    char virus_scanner[82];            /* The virus scanner command control
                                          code string. */
    int scanner_el;                    // expected scanner errorlevel
    char arq_string[10];               // ARQ connect string
    unsigned event_warn;               // Event warning time in minutes
    int bidir_area;                    // Bidir upload area
    unsigned connect_time;             // Time for connection
    int pass_feed;                     // Invalid PW feedback area
    char unused[622];
    // Bit fields 
    unsigned strip_kludge:1;           // 1-don't display ^A lines 
    unsigned strip_seen_by:1;          // 1-don't display SEEN-BY: lines 
    unsigned sys_oc:1;                 /* 1-closed system, don't allow new
                                          users during normal logon */
    unsigned view_pwd:1;               /* 1-View password locally when
                                          entering */
    unsigned usepark:1;                // 1-Use built-in HD parking utility
    unsigned text_shells:1;            // 1-text shells are enabled
    unsigned unused_bits:1;
    unsigned sysop_autologin:1;        // 1-Yes 
    unsigned alias:1;                  // 1-Yes 
    unsigned occ_dis:1;                // Disable OCC in messages, 1-Yes 
    unsigned save_lareas:1;            // 1-Save default areas
    unsigned remote_sysop:1;           /* 1-don't allow remote logins by sysop
                                          */
    unsigned ctsrts:1;                 // 1-Enable CTS/RTS flow control 
    unsigned useint:1;                 // 1-Force Internal Comm routines 
    unsigned dec_cmp:1;                // 1-Use decimal compare see docs 
    unsigned doorlr:1;                 // 1-pass locked rate to doors 
    unsigned exclude_local:1;          // 1-Exclude local logins




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 4

    unsigned bdir_chk:1;               // 1-Check all areas for duplicates
    unsigned use_diag:1;               // 1-Use Modem "diagnostics"
    unsigned lock_port:1;              // 1-Lock port
    unsigned local_offhook:1;          // 1-Offhook when on locally
    unsigned detect_terminal:1;        // 1-Autodetect ANSI/Avatar
    unsigned lock_noarq:1;             // 1-Lock port on non-ARQ connect
    unsigned long_usernums:1;          // reserved
  };

  The user record ("USERREC") consists of many entires of the following
  structure:

  struct user_rec { // Size: 534
    char name[36],realname[36];
    char password[16];
    char phoneno[11];                  //  Just the digits
    char street[41],city[21],state[3],zip[11];
    char birthday[9];                  /* MMDDYYYY, since C pukes at YYYY<1970
                                          */
    char comment[72];
    char genflags[72];                 /* Flag 1-genflags[0]&1, Flag
                                          23-genflags[2]&64 */
    time_t laston,firston,lastpc;      // Seconds since Jan 1,1970 
    unsigned num_uls;
    unsigned num_dls;
    long unsigned num_posts;
    char sec_level;
    char actual_sec_level;
    time_t time_used_today;
    unsigned calls_today;
    unsigned unused1;
    unsigned long num_calls;
    char lines_per_screen;
    char editor;                       // 0-lineed, 1-full screen  
    long sig_ptr;                      /* Pointer into Signs file, 0-no
                                          signature */
    long ann_ptr;                      //  Same, but announcements
    long res_ptr;                      //  Same, but resumes
    long rsig_ptr;                     //  Realname signature pointer
    unsigned long downk,upk;
    long todayk;
    char def_prot;                     //  default protocol (0-none)
    char unused1[3];
    unsigned long rmoney;              /* Money used in monetary system
                                          (points) */ 
    unsigned long cmoney;              /* Money contributed to Net Mail in
                                          cents */
    unsigned long timebank;            /* Amount of time in time bank, seconds
                                          */




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 5

    unsigned user_number;              /* This is a number between 0 and 65534
                                          which represents a static user
                                          number for the user and should NEVER
                                          be changed */
    unsigned unusedu;
    unsigned long user_vars[10];       // User variables
    time_t expdate;                    /* Subscription expiration time, should
                                          be midnight of a date or it may not
                                          work properly. */
    int marea,farea;                   // Save default areas
    char mgroup,fgroup;                // Saved group numbers
    char unused_spc[70];               // Unused space 
    unsigned sex:1;                    // 1-Female,0-Male 
    unsigned deleted:1;                // 1-Yes 
    unsigned screen_pause:1;           // 1-Yes 
    unsigned one_key:1;                // 1-One key, 0-full line 
    unsigned alert:1;                  // 1-Yes 
    unsigned xpert:1;                  // 1-Expert mode on 
    unsigned nokill:1;                 /* 1-Don't delete if user hasn't called
                                          in a while. */
    unsigned hidden:1;                 // 1-Don't show in userlist 
    unsigned guest:1;                  // 1-Is a guest user
    unsigned fs_viewer:1;              // 1-Use Full Screen Viewer
    unsigned mn_dnd:1;                 // Multinode do not distrurb
  };

  The file USERREC.IDX consists of the following structure:

  struct user_idx {
    unsigned long name_crc;            // 32-bit CRC of name
    unsigned long realname_crc;        // 32-bit CRC of realame
    unsigned user_number;              // 0-65534
  };

  Each record corresponds to the record in the USERREC file.  The 32 bit CRC's
  are calculated after converting the names to uppercase and use routines
  given in the May 1992 issue of Dr. Dobb's Journal.

  The file RETURN.INF, created when running a door, consists of the following
  structure.  When returning from a door, Mutant reads this file back in and
  any and all changes to the file take effect.

  struct on_line {// Size: 1000
    unsigned long currbaud;            /* Baud rate used in time calculations
                                          */
    char hangup;                       /* non zero-user has hungup/was hungup
                                          */
    char connect_code;                 /* The connect code if not decimal
                                          compare,49-dec_cmp */




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 6

    time_t timeon;                     // Logon time of user 
    time_t time_per_day;               // in seconds
    struct user_rec thisuser;          // The user online 
    unsigned record_number;            /* The record number 0-x of the user,
                                          this times sizeof(struct user_rec)
                                          is the offset into USERREC */
    unsigned unusedu;
    float flt_reserved;                // reserved
    char currmenu[20];                 // The name of the current menu 
    unsigned long uvars[5];            // Temporary user variables
    char varuser[36];                  /* The user who posted feedback, etc.
                                          */
    int marea,farea;                   /* Marea-the default message area,
                                          Farea-the default file area */
    char msg_group,file_group          // Current groups
    long event_time;                   // Time of next forced event, -1 if no
                                          event pending
    char temp_levent[81];              /* Temporary logon event, overrides
                                          logon events */
    char vstring[3][81];               // Not implemented 
    char vflags[4];                    // Temporary flags 
    char rip_rev[6];                   /* if rip_rev[0]==0, user does not have
                                          RIP, else contains version */
    unsigned udr;                      // Up/Down ratio (percent)
    unsigned udkr;                     // Up/Down KB ratio (percent)
    unsigned pcr;                      // Post/Call ratio (percent)
    int k_per_day;                     // -1, unlimited
    int calls_per_day;
    int prv_per_call;
    int pub_per_call;
    int net_per_call;
    int chat_per_call;
    int prv_this_call;
    int pub_this_call;
    int net_this_call;
    int chat_this_call;
    unsigned in_com:1;                 /* 1-get input from com port, remote
                                          logons only */
    unsigned out_com:1;                /* 1-send output to com port, remote
                                          logons only */
    unsigned ansi:2;                   // 1-ANSI 
    unsigned flg_reserved:1;           // reserved
    unsigned ingrfx:1;                 // 1-in graphics mode 
    unsigned ignorecost:1;             // 1-No file cost checking
    unsigned chatcall:1;               // 1-User is paging the sysop 
    unsigned sysopnext:1;              /* 1-Do a local logon after user logs
                                          off */
    unsigned quitnext:1;               // 1-Quit the BBS after user logs off 
    unsigned onlocal:1;                // 1-On locally 




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 7

    unsigned downnext:2;               // Not implemented
    unsigned voted:1;                  // 1-user has voted this call
    unsigned posted:1;                 // 1-user has posted
    unsigned uploaded:1;               // 1-user has uploaded
    unsigned download:1;               // 1-user has downloaded
    unsigned arq_connect:1;            // 1-reliable (arq) connection
  };

  Notes about RETURN.INF
  ----------------------
  1. You must modify "thisuser" if you want to modify the user online.  Mutant
  does not write the user to disk before shelling and it will write this one
  back out to disk when they logoff.

  2. If you reorganize USERREC, you must reset "record_number":


  record_number=file_pos[user]/sizeof(struct user_rec)

  So, if the user is written to offset 0 of USERREC, the record_number is
  zero.

  3.Timeleft(in seconds)=time_per_day - (time_now - timeon +
  thisuser.time_used_today).  If event_time>=0 and event_time - time_now is
  less than timeleft, then, timeleft=event_time - time_now.  Time_now is the
  current time in seconds since midnight of Jan 1, 1970.


  The WFC caller data is usually stored in a file called SYSSTAT.DAT and
  consists of the following structure:

  struct sys_status { // Size: 150
    unsigned long todayused;           /* Time BBS has been used today in
                                          seconds */
    unsigned long todaymsgs;           // Number of messages posted today
    unsigned long todayuls;            // Number of uploads today
    unsigned long todaydls;            // Number of downloads today
    unsigned numnew;                   // Number of new users today
    unsigned callstoday;               // Number of calls today
    long time_started;                 // The time this file was created
    long hours[24];                    // Time user per in hour in minutes
    long days[7];                      /* Time used per day of the week in
                                          minutes */
    unsigned chattype:2;               /* 0-use hours,1-force off, 2-force on
                                          */
    unsigned sysophasmail:1;           // not used
  };

  The list of callers today is stored in a file called PREVCALL.DAT and




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 8

  consists of many entires of the following:

  struct prev_callers { // Size: 74
    char name[36];
    int node;
    unsigned long baud;                // 0xFFFFFFFF is local 
    char from[26];                     // City, State 
    long timeon,timeoff;               // in seconds 
  };

  There are three files associated with the message base record.  The first,
  x.DTA where 'x' is the message base number, consists of one or more
  zero-terminated messages.  The second, x.IDX consists of the base_rec
  structure defined below which defines information about the message base
  followed by multiple instances of the idx_rec structure which can
  information about each message:

  struct base_rec {// Size: 960
    char name[31];                     // Name of the base 
    char access[77];                   // SACS to access base in lists
    char groups[4];                    // not implemented
    char anon1[36];                    // Anonymous string 1
    char anon2[36];                    // Anonymous string 2 
    char spon_alias[36];               // Alias sponsor(s) can use 
    char spon_to[36];                  /* Who to send the message to if sent
                                          to spon_alias */
    char sponsor[52];                  // SACS to be a sponsor
    char post[52];                     // SACS to post
    char anon[52];                     // SACS to post anonymously
    char copy[52];                     // SACS to post multiple copies
    char private[52];                  // SACS to post private messages
    char rdprv[52];                    // SACS to read private messages
    char viewanon[52];                 /* SACS to see actual users of
                                          anonymous msgs. */
    char afsacs[52];                   // SACS to attach files
    char crsacs[52];                   /* SACS to set crash bit in netmail
                                          messages */
    char invsacs[52];                  // SACS to make messages invalid
    char origin[52];                   /* If blank, use default in sys_config
                                          */
    char msgpath[64];                  // .MSG file path
    unsigned max_age;                  /* Maximum age of a message, 0-infinite
                                          */
    unsigned max_msgs;                 /* Maximum messages, 0-infinite (never
                                          use) */
    unsigned del_recv;                 /* Days after receipt of message before
                                          deletion */
    unsigned active;                   // Number of messages in the base 
    unsigned lstmsg;                   /* This plus one will be the next




  --- Mutant BBS v1.1 Structures Documentation ---                      Page 9

                                          message number posted */
    unsigned annmsg;                   // Annoucement message number 
    int zone,net,node,point;           /* If zone==0, use default in
                                          sys_config */
    int pmoney;                        /* amount to add to user's rmoney after
                                          posting */
    int  ra;                           // Echomail Reply Area
    char unused[40];
    unsigned anontype:3;               /* 0-None,1-Anon 1 only,2-Anon 1&2
                                          only,3-change alias, 4-Force Anon 1,
                                          5-force change alias */
    unsigned echoit:2;                 // 0-None, 1-Echo Mail, 2-Net Mail 
    unsigned pub_priv:2;               /* 0-public&private,1-public
                                          only,2-private only, 3-To All */
    unsigned realnames:1;              // 1-Use realnames in to/from fields
    unsigned afcrsh:1;                 /* 1-set crash bit if files attached
                                          (netmail) */
    unsigned dr:1;                     // 1-send replies to all as default 
    unsigned autoks:2;                 /* 0-no,1-yes,2-ask (netmail kill sent)
                                          */
    unsigned reserved:4;
    struct msg_filter {
      unsigned strip_hi_bits:2;        /* 1-strip chars>127, 0-no, upper bit
                                          is reserved. */
      unsigned strip_lo_bits:1;        // 1-strip chars<32, except ^A, ^M
      unsigned convert_ansi:1;         // 1-ESC->`
      unsigned strip_color:2;          // 0-no, 1-yes, 2-to ANSI color
    } f;
  };

  struct idx_rec {// Size: 296
    char title[72];
    char from[36];                     // Who message is from as posted
    char rfrom[36];                    // Who message is really from 
    char to[36];                       // Who message is to as posted
    char rto[36];                      // Who message is really to
    time_t time;                       // Time mssage was posted 
    int ozone,onet,onode,opoint;       // Set to our node upon posting 
    int dzone,dnet,dnode,dpoint;       /* Upon posting, Mutant sets to 0 if
                                          echomail/local, otherwise
                                          destination address */
    unsigned long msgptr;              // Start of message in *.DTA 
    unsigned msgnum;                   // Message number 1-65535 
    unsigned fchain;                   // Next message in reply chain 
    unsigned bchain;                   // Prev message in reply chain 
    unsigned reply;                    // Reply to this message 
    unsigned cost;                     // Cost of message (set in Netmail)
    struct fido_flags {
      unsigned private:1;              // Msg is private




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 10

      unsigned crash:1;                // Send msg with Crash Priority
      unsigned received:1;             // User Received message
      unsigned sent:1;                 // Message has been exported
      unsigned file_attach:1;          // File(s) attached
      unsigned in_transit:1;           // Not used internally
      unsigned orphan:1;               // Not used internally
      unsigned kill_sent:1;            // Delete when exported
      unsigned local:1;                // Msg posted on this BBS
      unsigned hold_pickup:1;          // Not used internally
      unsigned unused:1;
      unsigned freq:1;                 // Not used internally
      unsigned rreq:1;                 // Not used internally
      unsigned receipt:1;              // Not used internally
      unsigned areq:1;                 // Not used internally
      unsigned fureq:1;                // Not used internally
     /* If not used internally, the bits can still be set for use by an
  external message processor. */
    } f;
    struct extfido_flags {             /* None are used internally, except to
                                          generate ^AFLAGS */
      unsigned direct:1;
      unsigned immediate:1;
      unsigned del_sent:1;
      unsigned trunc_sent:1;
    } e;                                
    char unused[40];
    unsigned deleted:1;//1-Yes 
    unsigned no_kill:1;/*1-Don't let msg expire or count in max_msgs */
    unsigned invalid:1                 // 1-Message is invalid
    unsigned reserved:6;
  };

  The third file is x.LR.  A user's base information is stored here.  The
  offset to the user's record in this file is user.msgrnum*3L.  

  struct lastread { // Size: 3 (not word aligned)
    unsigned lastread;                 // Last read message number
    char flag;                         /* If bit 0 is set, this base is not
                                          scanned in combined mode.  Other
                                          bits are reserved */
  };

  Two files deal with all the message bases. The first is ECHOINFO.DAT.  This
  file is created/appended to whenever a user posts a message in an echomail
  or netmail base.  It's format is the area number (2 bytes, 0-999) followed
  by the message number (2 bytes).  Echo/netmail processors should use this
  file and set the message number to zero once it's processed a message. 
  Also, if the file is all zeros, deletetion is recommened.  Mutant will add
  1024 to an area number if the message has already been exported by Mutant.




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 11

  The second is INDEX.MSG.  This is used during area changes.  It is in the
  following format:

  struct area_index {
    char name[31];                     // area's name
    char access[77];                   // area's access SACS
    char gropus[4];                    // not implemented
    int area;                          // area number
  };

  Only bases which are actually created should be in this file.  If it is
  missing when Mutant checks it's files, it will rebuild it.

  NOTE: In the message text, Mutant adds the following:
                                       ^AMSGID: xxxxxxxx zone:net/node.point
  where "xxxxxxxx" is a hexadecimal number, and the address is the base or
  system configuration address.  Also, when replying, if a "^AMSGID:x" line is
  found with 'x' being a string less than 80 characters, Mutant will create a
  "^AREPLY:x" line in the reply message.

  Contrary to other BBSs, Mutant stores it's file listings in a record format
  and not in a text file.  There are two files associated with each file area. 
  First, x.INF where x is the file area, contains the AREA structure which
  defines information about the area followed by zero-terminated extended file
  descriptions. The second, x.LST contains the actual file list as defined in
  the TFILE structure:

  struct AREA { // Size: 630
    char name[31],access[77];
    char groups[4];
    char upload_path[64];              // in uppercase please!
    char up[52];                       // upload SACS
    char dv[52];                       // Download unvalidated files
    char sponsor[52];                  // Sponsor SACS
    char vv[52];                       // See unvalidated files
    char freefiles[52];                // SACS for free files
    char addsacs[52];                  // SACS to add SACS to a file.
    int cost_base;                     // K divisor for file cost
    int cost_comp;                     // this*file cost to uploader
    int comm_pcnt;                     // file cost*this/100 to uploader
    float utm;                         /* Add time for uploads*utm to user's
                                          timeleft */
    char defext[4];                    /* Default file extension without the
                                          '.' */
    unsigned show_offline:1;           // 0-Show offline files 
    unsigned auto_cost_comp:1;         // 1-Makes cost_base&comp work
    unsigned auto_validate:1;          // 1-Validate files, Not recmd.
    unsigned user_cost:1;              // 1-allow users to set cost
    unsigned cd_rom:1;                 // 1-Mutant will copy file(s) to the




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 12

                                          temporary directory before actually
                                          sending them.
    unsigned no_archive:1;             // 1-disable unpack operations
    char unused[128];
  };

  struct TFILE { //Size: 256
    char filespec[81];
    char desc[81];
    unsigned cost;                     /* User must have at lease cost in
                                          rmoney */
    char password[18];
    time_t up_time;                    /* Time uploaded/added to system, not
                                          file time */
    time_t dos_time;                   /* The actual file date according to
                                          DOS. */
    long file_size;                    /* The size of the file in bytes, if -
                                          1, the file is offline */
    char who[36];                      // Who uploaded the file 
    unsigned long numdls;              // Times downloaded 
    long ed_ptr;                       /* Pointer into .INF for extended
                                          description,-1-none */
    char unused[16];
    unsigned validated:1;              // 1-Validated 
    unsigned use_ddate:1;              // 1-Use file date for new files check
    unsigned arch_test:1;              //  0-File passed archive test
    unsigned user_flags:2;             //  The two flags you define.
    unsigned freefile:1;               //  file is free
  };

  The file transfer directory also contains INDEX.FIL which is the same as the
  index for message bases except it's for file bases.

  Groups are stored as GROUPS.MSG and GROUPS.FIL in the system files
  directory.  The format is:

  struct group { // Size: 256
    char name[31];
    char sacs[81];
    char unused[144];
  };

  The file PRTCLS.DAT contains the information about external protocols. The
  first two bytes of this file are a word indicating the number of protocols
  available followed by the following structure:

  struct protocol {// Size: 768
    char name[21],key,sacs[81],up[128],down[128],logfile[81],dok_codes[41];
    char uok_codes[41],de_codes[41],ue_codes[41],lc_codes[81];




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 13

    char batch_type;                   /* 0-none,1-batch,2-not batch send, but
                                          receive,3-bidir */
    float efm;                         // Efficency modifier 
    int record_len,filename_line,filename_field,ok_line,ok_field;
    int error_line,error_field,lc_line,lc_field,cps_line,cps_field;
    char unused[46];
  };

  The menus are stored in two files. First, MENUS.IDX contains a word at the
  beginning of the file defining the number of menus followed by the following
  structure:

  struct menu_index { // Size: 34
    char name[20];                     // Menu name 
    long fpos;                         // Start of menu items in MENUS.DTA 
    long epos;                         /* Start of next menu in MENUS.DTA,
                                          i.e. start reading at fpos and read
                                          until file position is epos */
    int numcols;                       /* Number of columns to display generic
                                          help screens */
    long menuflags;                    /* bits 0&1=1-force one key input
                                          during this menu, =2-force full line
                                          input during this menu
                                          bit 2-Don't use global */
  };

  The second file, MENUS.DTA is a very dynamic file.  Each record defines each
  menu item which consists of the following structure plus, the key string of
  length keylen, if keylen is not zero (which should never happen); the data
  of length datalen, if datalen is not zero; the access (SACS) of length
  accesslen, if accesslen is not zero; and the generic help screen
  information of length helplen if not zero.

  struct menu_data { // Size: 12
    unsigned comtype;                  // Command Code 
    unsigned nowait:1;                 // No longer used 
    unsigned valid:1;                  // Used internally 
    unsigned keylen;                   // Length of "key" in bytes 
    unsigned datalen;                  // Length of data 
    unsigned accesslen;                // Length of access 
    unsigned helplen;                  // Length of generic help info 
  };

  Events are stored in EVENTS.DAT.  Like other files, the first two bytes of
  the file are a word defining the number of events in the file. This is
  followed by the following structure:




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 14

  struct event { // Size: 168
    char name[69];                     // Name of the event 
    char runfile[81];                  /* Really is optional data for the
                                          event */
    int  node;
    long data;/* Varies depending on when field 
                   when      data
                     0       Bit 0-Sunday,Bit 6-Saturday
                     1       Day of the month
                     2       month*100+day of month
                     3       0-Always, 1-Posted,2-uploaded,3-downloaded,
                             4-voted
                     4       low word-min area,hi word-max area
              */
    char type;                         /* 0-Mutant,1-External,2-Shell,
                                          3-Menu,4-Logon */
    char when;                         /* 0-Weekly, 1-Monthly, 2-Yearly, 3-at
                                          logoff,4-E/N Posted,5-Int. E/N
                                          posted */
    int h,m;                           // Hour, Minute of start of event 
    long lastrun;                      // Time event was last run 
    unsigned forced:1;                 /* Force event to occur at time
                                          specified */
    unsigned active:1;                 // Event is active, 0-ignore event 
    unsigned offhook:1;                /* 1-Send modem offhook before running
                                          */
    unsigned down:1;                   // 1-down for event
    unsigned running:1;                // used internally, set to 0!
  };

  Archive configuration info. are stored in ARCHIVE.DAT.  First two bytes
  define the number of the following structures defined in the file:

  struct archive { // Size: 512
    char name[51];
    char extension[4];                 // Without '.' 
    char unpack[51];                   // Command to unpack 
    char pack[51];                     // Command to pack 
    char view[51];                     // Command to view 
    char addcomment[51];               // Command to add comment 
    char validity[51];                 // Command to check validity 
    int  success;                      // Success errorlevel 
    long sfxoffset;                    // SFX file offset
    char sfxsig[51];                   // SFX signature
    char comment[51];                  /* The comment or comment filename to
                                          add */
    char include[51];                  /* File to include (for a BBS Ad
                                          program, etc.) */
    char unused[41];




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 15

    unsigned direcs:1;                 /* 1-Can recursively pack/unpack
                                          subdirectories */
    unsigned pref:1;                   // 1-Preferred archive format
    unsigned endexe:1;                 // 1-end of exe+sfxoffset = sig
    unsigned unflags:13;
  };

  Voting questions, "*.vte" contain the following:

      offset    length    Description
        0         81      SACS to vote on the question
        81        81      SACS to add choice to the question
        162       81      The question itself
        243        4      Total number of user's voting on the question
        247        4      Total voting for choice 1.
        251        4      Total voting for choice 2.
        351       71      Choice 1
        422       71      Choice 2
        ...       71      All 0's indicating end of choices.  This is
                          present even if there are 26 choices already
                          defined.
        ...+71    36      A user name
        ...+107    1      The choice they voted for
                          User's are sorted alphabetically and should not
                          contain deleted users.  When you delete a user
                          in the user editor, Mutant removes the user from
                          all voting questions.

  The BBS list is stored in two files.  The first, BBSLIST.TXT consists of
  zero-terminated information about each BBS.  The second, "BBSLIST" contains
  multiple entries of the following:

  struct bbs_file {// Size: 76
    char name[42];
    char phoneno[11];
    char type[11];
    char baud[10];
    long text_pos;                     /* Text_pos offset into BBSLIST.TXT,
                                          -1-no entry */
  };

  The file "DOORSTAT.DAT" in the system files directory contains the
  information about door usage:

  struct door_stats { // Size: 44
    char name[32];                     // Name of the door
    long cnt;                          // Times Used
    long ttime;                        // Total time used in seconds
    long last;                         // Last time used in C time




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 16

  };

  The files "SIGNS","ANNS","RESUMES" consisted of multiple zero-terminated
  messages corresponding to each user's pointer into these files.  The first
  byte of these files are usually garbage to prevent an offset of zero.

  There are two types of files associated with multinode usage.  The first,
  NODE.x where 'x' is the node number contains the node_info structure which
  define information other nodes can list about the current node and may
  contain any number of node_msg structures which define "messages" to the
  node:

  struct node_info { // Size: 280
    char username[36];                 // User name if one is online 
    char from[26];                     // City, State of user 
    unsigned long baud;                // Baudrate, 0xFFFFFFFF is local 
    int status;                        /* see the list in PROMPTS.TXT, or you
                                          write to me and request BST.H which
                                          lists these values */
    long qpos;                         /* Offset of next message to get, 0-no
                                          messages */
    char door_spec[32];                // The door being run if specified
  };

  struct node_msg {// Size: 88
    int from,type,dlen;                // From-node number that sent msg,
                                       // dlen-length of data 
    char data[82];                     // Not necessarily text 
  /* Type  Description                    Data
      0    Are you there?(Mutant no longer uses this)
      1    Yes, I'm here!(Mutant will send this upon a type 0)                 
      
      2    From node does not wish to be disturbed
      3    Trashed User Record - Mutant reloads user after searching for it. 
  If not found, results could be unpredictable.
      4    Modified a user                Record Number (0-?)
      5    Message from use on node       Text message
      6    Chat message                   Text message
      7    User left group                Who
      8    User kicked out                Who
      9    User entered group             Who
     10    Chat message from sysop        Text message
     11    Lock Node (temp logon event)   SACS
     12    Take down node (quit next)     Y or N
     13    Interrupt node (hang up)       Hangup msg
     14    Go down for event              '0'-Yes, '1'-offhook, '2'-go back up
     20    What's your screen look like
     21    Here's My Screen               File offset
  */




  --- Mutant BBS v1.1 Structures Documentation ---                     Page 17

  };

  If you are writing a Mutant specific door, and modify USERREC in anyway, you
  should send at least Message 4 to all nodes except your current node unless
  you just modified the current user.

  Commands 20 and 21 are designed for some sort of node utility.  When Mutant
  receives a command 20, it will create (or append to) SCRN.orgnode and write
  the terminal window (24*160 bytes).  It will then send a message type 21
  back to the origin node with the file offset of the screen.

  The second file, X.CHT defines chat groups.  These files should be deleted
  when there is no-one chatting in the group.  It consists of the chat_group
  structure which defines the chat area followed by one or more chat_people
  structures which define who is chatting or who has been invited to chat:

  struct chat_group {//Size: 74
    char name[36],sponsor[36];         /* Name-Name of group, Sponsor-who
                                          started it */
    int private;                       // 0-no, 1-yes 
  };

  struct chat_people {//Size: 40
    char name[36];
    int status;                        /* 2-invited, 0-not here, 1 or
                                          3-present in the group */
    int node;                          // Node the user is on 
  };
