home *** CD-ROM | disk | FTP | other *** search
/ RBBS in a Box Volume 1 #2 / RBBS_vol1_no2.iso / add2 / slbbs30b.zip / FILEDEF.LIB < prev    next >
Text File  |  1988-07-29  |  20KB  |  492 lines

  1.  
  2.  
  3. { FILEDEF.LIB }
  4. { File Definitions for Searchlight BBS, ver 1.28 }
  5.  
  6. { (C) Copyright 1987,88 by Frank LaRosa. ALL RIGHTS RESERVED.  }
  7.  
  8. { This file contains type declarations for the files created by Searchlight
  9.   BBS.  We are releasing this information to the public in order to foster
  10.   the development of third party DOORware and utility software.
  11.  
  12.   IF YOU USE THIS INFORMATION: Please follow the guidelines carefully.
  13.   Searchlight Software cannot be held responsible for failure of third party
  14.   software.  We reserve the right to change anything in these file definitions
  15.   although we will try to keep things as consistent as possible.
  16.  
  17.   All source code is Turbo Pascal 3.0.  If you are programming in another
  18.   language, note that STRING data types- string[n]- consist of a one-byte
  19.   string length followed by an array of n characters.  Thus, sizeof(string[n])
  20.   equals n+1.  Also note that the first record of a file is record 0, while
  21.   the first element in an array is (usually) 1.  For ordinal types, the
  22.   ordinal value of the first element is always 0.              }
  23.  
  24.  
  25.  
  26. { The following files make up the core of the BBS. They will reside in the 
  27.   current directory when the BBS is run.                       }
  28.  
  29. const configspec  = 'CONFIG.BBS';   { Configuration & Current Info }
  30.       userspec    = 'USER.BBS';     { User File }
  31.       indexspec   = 'INDEX.BBS';    { Sub-Board Index }
  32.       textspec    = 'MESSAGE.BBS';  { Message Texts File }
  33.  
  34.       logspec     = 'LOG.BBS';      { Caller Log }
  35.       quotespec   = 'QUOTES.BBS';   { Logoff Quotes }
  36.       dirspec     = 'FILEDIR.DEF';  { UL/DL Directory Definitions }
  37.       doorspec    = 'DOORS.DEF';    { External Program Definitions }
  38.  
  39. const maxsub    =  24;  { max number of sub boards }
  40.       maxmsg    = 290;  { max number of messages per sub }
  41.       blocksize =  90;  { block size of message texts }
  42.       logsize   =  75;  { size of last caller log }
  43.       maxdir    =  35;  { max number of file directories }
  44.  
  45.  
  46. Type  { Preliminary Type Definitions }
  47.  
  48.      timetype = record   { time }
  49.        hour: byte;
  50.        minute: byte;
  51.      end;
  52.  
  53.      datetype = record   { date }
  54.        year: byte;
  55.        month: byte;
  56.        day: byte;
  57.      end;
  58.  
  59.      pwtype = array[1..3] of byte;  { 3-byte password }
  60.  
  61.      int3 = record               { long 3-byte integer }
  62.        low: integer;
  63.        hi: byte;
  64.      end;
  65.  
  66.      RSbaud = (B110,B150,B300,B600,B1200,B2400,B4800,B9600,B19200);
  67.        { rs232 baud rates }
  68.  
  69.      colortype = (NULLCOLOR,     { no color set }
  70.                   NORMAL,        { normal screen color for most i/o }
  71.                   INVERSE,       { inverse for input highlighting }
  72.                   COMCOLOR,      { color for command highlight }
  73.                   SUBCOLOR,      { subboard information }
  74.                   HEADCOLOR,     { color for headings }
  75.                   CHATCOLOR,     { chat mode color }
  76.                   SPECIAL,       { special prompts and messages }
  77.                   ERRCOLOR,      { error and warning messages }
  78.                   ALTCOLOR,      { alt. special color }
  79.                   PROMPTCOLOR ); { colour for prompts }
  80.  
  81.  
  82.  
  83.  
  84. Type  { File Type Definitions }
  85.  
  86.      Configtype = record   { format of CONFIG file }
  87.  
  88.        sysname: string[30];    { the name of the BBS }
  89.        syscalls: int3;         { total calls to system }
  90.        comport: byte;          { comm port to use, 1-4 }
  91.        bsupport: byte;         { baud rates supported }
  92.        newusers: boolean;      { new user registration }
  93.        bulletins: integer;     { pointer to bulletins }
  94.        progpath: string[40];   { path for program files }
  95.        textpath: string[40];   { path for text files }
  96.  
  97.        curruser: integer;      { current user ID number }
  98.        currboard: byte;        { current active sub board }
  99.        logtime: timetype;      { current time of logon }
  100.        remote: boolean;        { remote/local logon flag }
  101.        baudrate: rsbaud;       { caller's baud rate }
  102.        ansi: boolean;          { ANSI graphics mode indicator }
  103.        newlogon: boolean;      { set if main program not yet run }
  104.  
  105.        lastuser: integer;      { last user on the system }
  106.        lastquote: string[72];  { quote left by last user }
  107.        defaccess: byte;        { default new user access level }
  108.        deftimelimit: byte;     { default new user time limit }
  109.        rsactive: boolean;      { true if rs port active }
  110.        valaccess: byte;        { default validation access }
  111.        valtimelimit: byte;     { default validation timelimit }
  112.        deffile: byte;          { new user file access }
  113.        valfile: byte;          { validated file access }
  114.  
  115.        currdir: integer;       { current directory }
  116.        sysavail: boolean;      { sysop availability flag }
  117.        logfile: string[40];    { default log file }
  118.        paged: boolean;         { set if sysop paged }
  119.        timelimit: byte;        { time limit for this session }
  120.  
  121.        color: boolean;         { ANSI color mode indicator }
  122.        normback: byte;         { textbackground for normal }
  123.        invtext: byte;          { DEFUNCT }
  124.        invback: byte;          { textbackground for inverse }
  125.  
  126.        superuser: boolean;     { superuser alt-s status }
  127.        buffactor: integer;     { output buffer size }
  128.        hayes: boolean;         { unused }
  129.        maxmaillen: integer;    { max. lines in e-mail }
  130.        maxbulllen: integer;    { max. lines in bulletins }
  131.        laston: datetype;       { last logon date of current user }
  132.  
  133.        command: string[80];    { command line of currently active DOOR }
  134.        commtype: byte;         { command type }
  135.        commdir: string[80];    { default dir for command }
  136.        wp: boolean;            { write protection flag in door }
  137.  
  138.        relogtime: integer;     { min. time between logins }
  139.  
  140.        initstr: string[40];    { modem init string }
  141.        localstr: string[40];   { modem 'local' init string }
  142.        overpath: string[40];   { overlay path }
  143.  
  144.        abort: byte;            { abort type, for doors }
  145.        defaultpw: string[40];  { default password for uploads }
  146.        xratio: byte;           { dl/ul ratio }
  147.        activlog: boolean;      { activity logging flag }
  148.        presshard: byte;
  149.        modemmsg: boolean;      { true for modem msg baud detect }
  150.  
  151.        colorchart: array [NORMAL..PROMPTCOLOR]
  152.          of byte;              { color definitions }
  153.  
  154.        indoors: boolean;       { set if doors menu active }
  155.  
  156.        subtext: array[1..maxsub]
  157.          of boolean;           { subboard text message flags - these flags are
  158.                                  reset with each call, and set when a user 
  159.                                  enters the corresponding subboard         }
  160.        dirtext: array[1..maxdir]
  161.          of boolean;           { file dir text message flags }
  162.  
  163.        incpath: string[40];    { path for message include files }
  164.        sysfile: string[40];    { path/filename for DOORS setup file }
  165.  
  166.      end;
  167.  
  168. {   NOTES:
  169.  
  170.   The CONFIG file is a fixed length, one record file containing the above
  171.   information.  Typically, a DOORware or utility program will read the config
  172.   file to pick up information about the currently active user, comm port,
  173.   etc.  All items from the CONFIG.COM program are stored here.
  174.  
  175.   The BULLETINS field is a two-byte pointer into the MESSAGE.BBS file,
  176.   indicating the header record of the first bulletin.  The second bulletin
  177.   is chained onto the first via the "ID" field in the message header, etc.
  178.   A word of zero indicates the end of the chain.
  179.  
  180.   BSUPPOSRT is a bit field.  Bit 0 of this byte is set if 300 baud is 
  181.   supported, bit 1 is set for 1200 baud support, etc.
  182.  
  183.   ALL FIELDS ARE RESERVED.  Searchlight Software reserves the right to use
  184.   all unused fields in future versions of Searchlight BBS.  If you want to 
  185.   save your own information, you should create your own data files indexed
  186.   on user names and/or record numbers.  This goes for the rest of this file
  187.   as well.                                                         }
  188.  
  189.  
  190.  
  191.  
  192.  
  193. type Usertype = record   { format of USER file }
  194.  
  195.        name: string[25];       { user name }
  196.        location: string[20];   { user location }
  197.        passwd: pwtype;         { password }
  198.        cksum: byte;            { checksum of name }
  199.        firston: datetype;      { date of first logon }
  200.        laston: datetype;       { date of last logon }
  201.        calls: int3;            { total number of calls }
  202.        systype: string[15];    { system type }
  203.        phoneno: string[12];    { phone number }
  204.        lasttime: timetype;     { time of last logon }
  205.        xproto: byte;           { default file xfer protocol }
  206.        extra: string[7];       { reserved }
  207.  
  208.        access: byte;           { BBS access level }
  209.        faccess: byte;          { file system access level }
  210.        access2: byte;          { unused }
  211.        timelimit: byte;        { time limit in minutes }
  212.        uploads: integer;       { Kbytes uploaded }
  213.        downloads: integer;     { Kbytes downloaded }
  214.  
  215.        firstmsg: integer;      { pointer to first message in mailbox }
  216.        lastmsg: integer;       { pointer to last message in mailbox }
  217.  
  218.        lastread: array[1..maxsub]
  219.          of integer;           { last message read pointers }
  220.  
  221.        spare: string[7];       { reserved }
  222.  
  223.        extend: integer;        { reserved }
  224.        parent: integer;        { pointer to parent node }
  225.        left,right: integer;    { pointers to child nodes }
  226.  
  227.      end;
  228.  
  229. {   NOTES:
  230.  
  231.   The USER file is structured as a binary tree.  Record 1 is the root of the
  232.   tree, and will always contain the SYSOP account.  To traverse the tree, use
  233.   the pointers LEFT and RIGHT.  The PARENT pointer will always point to a 
  234.   node's parent node.  Record zero contains the pointer to the free record
  235.   chain; the pointer is stored in the PARENT field.  Also in record zero,
  236.   field RIGHT contains the total number of users in the file.
  237.  
  238.   A deleted user record is marked with a -1 in the LEFT field and removed 
  239.   from the tree.  If you process the user file sequentially instead of using
  240.   tree traversal, you must ignore deleted records.
  241.  
  242.   If you write programs to update this file, you must be extremely careful.
  243.   All data structures must be maintained, including the free record list,
  244.   the tree pointers, the parent node pointers, etc.  Also note that it is
  245.   extremely important that data is never moved; Searchlight BBS maintains
  246.   pointers to absolute record numbers in this file, and expects that a
  247.   user's record will ALWAYS OCCUPY THE SAME PHYSICAL RECORD on the disk.
  248.   Consequently, user programs can safely store record numbers for fast access
  249.   to the user file.  You must, however, ensure that the record still contains
  250.   valid information each time you access it.  The fastest way to do this is
  251.   to store a checksum of the user name with the record number, comparing it
  252.   to the CKSUM field above.  A checksum failure indicates the user was 
  253.   deleted from the system and the record reused by another user.
  254.  
  255.   Mail is stored as a pointer to the header of the first message in the 
  256.   mailbox (firstmsg).  Subsequent messages are linked via the ID field in
  257.   the message header, with a zero word indicating the end of the list.
  258.   The user file also maintains a pointer to the header record of the last
  259.   message in the mailbox (lastmsg); this pointer is used to quickly append
  260.   messages to the mailbox without having to process the entire linked list.
  261.  
  262.   See notes below concerning passwords.                                }
  263.  
  264.  
  265.  
  266.  
  267.  
  268. type Indextype = record   { format of INDEX file }
  269.  
  270.        status: byte;           { access level }
  271.        name: string[25];       { sub board name }
  272.        subsysop: integer;      { ID of sub-sysop }
  273.  
  274.        messages: integer;      { number of messages on sub }
  275.        next: integer;          { next MSG ID number }
  276.  
  277.        index: array[1..maxmsg]
  278.          of integer;           { pointers to messages }
  279.                                { maxmsg = 290 for version 1.28-1.29,
  280.                                  maxmsg = 480 for extended vesions }
  281.  
  282.        maxmsglen: integer;     { max. message length }
  283.        spare: array [1..18]
  284.          of byte;              { reserved (29 in extended versions) }
  285.  
  286.      end;
  287.  
  288. {   NOTES:
  289.  
  290.   The INDEX file is a 24-record file defining the 24 message subboards.
  291.   Each subboard contains up to <maxmsg> messages (maxmsg=290).  The messages
  292.   are stored as two-byte pointers into the MESSAGE.BBS file.  The first
  293.   record of a message contains the header information, followed by a pointer
  294.   to the text.
  295.  
  296.   MSG ID number is a sequential number that is incremented with each new
  297.   message posted.  It is stored in the header of each message, and in the
  298.   "last message read" fields in the USER file.  Since this number is always
  299.   increasing, it is used for the NEW scan to determine which messages are
  300.   new, regardless of how many deletions have taken place.
  301.  
  302.   In shareware versions, the 'index' array consists of 290 two-byte 
  303.   numbers, yielding a total record size of 633 bytes. In extended versions,
  304.   the index size is increased to 480 words and the reserved area to 29
  305.   bytes, giving a record size of 1024 bytes. This difference must be kept
  306.   in mind if you will be writing software designed to process files used
  307.   with either version.
  308.  
  309.   It is important to note that messages do not, for all practical purposes,
  310.   have numbers.  The index file is simply an array of pointers.  To delete
  311.   a message, you remove the pointer from the array, and move all subsequent
  312.   pointers up by one.                                            }
  313.  
  314.  
  315.  
  316.  
  317.  
  318. type Textype = record   { format of MESSAGE file }
  319.  
  320.        next: integer;   { next record of message }
  321.        copies: integer; { number of active copies }
  322.  
  323.        case header: boolean of
  324.  
  325.          true:  (       { message header }
  326.            id: integer;       { message ID number (public msg)/
  327.                                 next message pointer (mail/bulletin) }
  328.            from: integer;     { ID of sender }
  329.            cksum: byte;       { sender's checksum }
  330.            time: timetype;    { time recorded }
  331.            date: datetype;    { date recorded }
  332.            rd: int3;          { times read }
  333.            ffrom: string[25]; { forwarded-from }
  334.            subj: string[40];  { subject }
  335.            prot: boolean;     { purge protection }
  336.            reply: byte;       { times replied-to }  );
  337.  
  338.          false: (       { message text }
  339.            data: string[blocksize];                 );
  340.  
  341.      end;
  342.  
  343. {   NOTES:
  344.  
  345.   There are two types of records in the message file: header and text.  Header
  346.   records contain time, date, subject, etc.; text records contain message
  347.   text, a block at a time.  One block is a string of up to 90 characters.
  348.  
  349.   Messages are pointer structures.  The NEXT field points to the next block
  350.   of message text or contains zero to indicate the end of the chain.  If the
  351.   message is a public message, the ID field contains the "next message ID"
  352.   number from the INDEX file.  If the message is electronic mail or a 
  353.   bulletin, the ID field contains a pointer to the NEXT item in the mailbox
  354.   or next bulletin.  These pointers must be maintained if you add or
  355.   delete messages.
  356.  
  357.   Message text is stored in the DATA string.  DATA should always be of length
  358.   90 except in the last block.  Individual lines are truncated with the CR
  359.   character embedded in the data string, and one line can span two or more
  360.   records.  To recover the text of a message, you must de-block all lines
  361.   and then uncompress the message text.  A sample routine for reading messages
  362.   is included in the file READ.LIB.
  363.  
  364.   Record zero contains the pointer to the free record list (stored in the NEXT
  365.   field).  To store data in the message file, pop a record off the free list
  366.   or expand the data file if no free records exist.
  367.  
  368.   It is OK for more than one pointer to point to a message.  When this 
  369.   happens, the COPIES field of each record is incremented.  When a message 
  370.   is deleted, the COPIES field is decremented if it is greater than zero; 
  371.   otherwise the record is cleared and added to the free space list.      } 
  372.  
  373.  
  374.  
  375.  
  376. type Logtype = record  { LOG file }
  377.        head: integer;
  378.        users: array[1..logsize] of record
  379.          id: integer;     { user ID # }
  380.          time: timetype;  { time of login }
  381.          date: datetype;  { date of login }
  382.        end;
  383.      end;
  384.  
  385. {   NOTES:
  386.  
  387.   The caller log file is a simple circular list containing a log of the last
  388.   75 callers (LOG.BBS).  HEAD points to the beginning of the list.  The ID 
  389.   number is a pointer to the caller's record number in the USER.BBS file.   }
  390.  
  391.  
  392.  
  393.  
  394. type Quotetype = record  { QUOTES file }
  395.        name: string[25];   { their name }
  396.        quote: string[72];  { what they said }
  397.      end;
  398.  
  399. {   NOTES:
  400.  
  401.   The QUOTES.BBS file has no data structure; it is simply an array of quotes
  402.   and user names.  The names are stored as text rather than pointers.  This
  403.   file is updated by Searchlight BBS simply by picking a random record number
  404.   to overwrite.
  405.  
  406.   This file contains 75 records initially, but you can expand it.  If you
  407.   expand the file, Searchlight will use the new records automatically.  }
  408.  
  409.  
  410.  
  411.  
  412.  
  413. type Dirtype = record      { file directory format }
  414.  
  415.      active: boolean;
  416.      case integer of
  417.  
  418.      1: (     { normal data record }
  419.        name: string[12];     { filename }
  420.        descrip: string[40];  { description }
  421.        length: integer;      { length in 128-char blocks }
  422.        id: integer;          { ID of uploader }
  423.        date: datetype;       { date uploaded }
  424.        last,next: integer;   { ptrs to date sorted list }
  425.        left,right: integer;  { tree pointers }
  426.        times: int3;          { # of times downloaded }
  427.        passwd: pwtype;       { password }
  428.        extra: string[9];     { reserved }      );
  429.  
  430.       2: (    { root record }
  431.         dataroot: integer;   { root of tree }
  432.         dateroot: integer;   { root of date chain }
  433.         freeroot: integer;   { root of free space chain }
  434.         files: integer;      { # of entries }    );
  435.  
  436.      end;
  437.  
  438. {   NOTES:
  439.  
  440.   Each file directory file contains two data structures: a binary tree keyed
  441.   on the file names, and a doubly-linked list keyed on the upload dates.
  442.   Record 0 contains the pointers to the root nodes, including the root to the
  443.   free record list.  The 'active' flag is set for valid nodes, reset for 
  444.   deleted data.  The binary tree does not contain parent node pointers as it 
  445.   does in the USER file.
  446.  
  447.   To traverse the tree, start with the dataroot pointer and follow the left
  448.   and right node pointers.  To follow the linked list, start with the dateroot
  449.   pointer and follow the next pointers.  If you update the file, you must 
  450.   maintain all pointers.
  451.  
  452.   See the note below on passwords.                                    }
  453.  
  454.  
  455.  
  456.  
  457.  
  458. { Additional Notes }
  459.  
  460. { PASSWORDS
  461.   ---------
  462.  
  463. All passwords are stored as 3-byte hash codes.  Here is the procedure to use
  464. to transform a string into a password:                                }
  465.  
  466.  
  467. Type pwstr = string[60];
  468.  
  469. Procedure Hash (s: pwstr; var r:pwtype);
  470.   { return modified 3-byte checksum }
  471.  
  472. var i,j: integer;
  473.  
  474. Begin
  475.   for i:=1 to 3 do
  476.     r[i]:=0;
  477.   j:=1;
  478.   for i:=1 to length(s) do begin
  479.     r[j]:=r[j]+ord(s[i]);
  480.     if (r[j] mod 2)=0 then begin
  481.       j:=j+1;
  482.       if (j=4) then j:=1;
  483.     end;
  484.   end;
  485. end;
  486.  
  487.  
  488. { To verify a password, hash it and compare the result with the stored hash-
  489.   code of the password in question.  You cannot "unhash" a stored password
  490.   in order to get the value of the password string.                    }
  491.  
  492.