Inside RiBBS A Comprehensive Description of RiBBS Formats Last update : 07/05/93 - RiBBS v2.10 This file was created for those who wish to write programs to compliment RiBBS, but require more information about the formats of various files that are read/created by the BBS and some of the variables being passed to its modules. It should be noted that the formats listed herein are subject to change without notice, which may affect the workings of programs written to follow them. Conventions -===========- Throughout this file, the following abbreviations will be used: (S) - String Data (Sx)- String Data, "x"=number of bytes (F) - Boolean Flag (B) - Byte Data (I) - Integer Data (R) - Real Number Data Note that (F) (Boolean Flag) data consumes a full byte of information eventhough only one bit within that byte is used to determine the TRUE/FALSE status of that flag. File and record offsets are expressed as a Hexadecimal number (prefixed by a "$" character) and then its Decimal equivalent, separated by a slash. For example, if a field starts at the tenth byte in a file (or record) its offset would be represented as: $0A/10 Userlog Format -==============- - UserIndex - First, the "UserIndex" file. This file's format is probably the simplest one of the system. It's purpose is to allow RiBBS to find a user's name with as little file reading as possible (thus making it relatively fast.) The format is as follows: ---------------------------- Record 1 - | User name (S32) | +--------------------------+ Record 2 - | User name (S32) | +--------------------------+ etc..... This file gets recreated by UserEdit each time that you delete an entry or change a user's name. It is also appended to when a new user logs on. The names here are in exactly the same order that they appear in the UserLog file. Thus, if you read UserIndex records and keep track of how many have been read by the time you find the name you are looking for, you can calculate the point in UserLog that that user's profile starts. - UserLog - The UserLog format contains a great deal more information on each user. It too is appended when a new user logs on and is rewritten from scratch when using the

urge option of UserEdit. Each record is 197 bytes long, and they are not in any particular order unless you've sorted them that way with a program such as USort. The one exception to this is the Sysop's record, which is always the first one. Each record looks like: Offset: ------------ --------------------------===>> ________________________ ________________________ $00/0 | Name (S32) | $20/32 | City (S20) | |----------------------+ |----------------------| $34/52 | State (S2) | $36/54 | Password (S8) | |----------------------+ |----------------------| $3E/62 | Date Last On (S8) | $46/70 | Access Flags (B) | -Note #1 |----------------------+ |----------------------| $47/71 | Export Toggle (B) | $48/72 | Uppercase Toggle (B) | -Note #2 |----------------------+ |----------------------| $49/73 | Clear Screen (B) | $4A/74 | # Uploads (B) | |----------------------+ |----------------------| $4B/75 | # Downloads (B) | $4C/76 | Time Limit (B) | |----------------------+ |----------------------| $4D/77 | Download Limit (B) | $4E/78 | Page Length (B) | |----------------------+ |----------------------| $4F/79 | Time Used Today (I) | $51/81 | Times Called (I) | |----------------------+ |----------------------| $53/83 | Access Level (I) | $55/85 | Kbytes Uploaded (I) | |----------------------+ |----------------------| $57/87 | Kbytes Down. (I) | $59/89 | Msgs Posted (I) | |----------------------+ +----------------------| $5B/91 | Download Points (I) | |----------------------+---------------------------------+ $5D/93 | Last Read Pointers (array of 50 Integers) | -Note #3 |----------------------+---------------------------------| $C1/193 | Active/Deleted (F) | $C2/194 | Page Pausing (F) | |----------------------+ |----------------------| $C3/195 | UD ? (F) | $C4/196 | Term Type (B) | -Note #4 +----------------------+ +----------------------+ -Note #5 A typical Basic09 TYPE statement to handle this might look like: TYPE uentry=name:STRING[32]; city:STRING[20]; state:STRING[2]; password, day:STRING[8]; flg,exp,ucase,clr,upl,dwl,timel,dlim,PAGL:BYTE; ttoday, called,lv,kup,kdw,msgs,dlpoint,lastread(50):INTEGER; del,pau,ud:BOOLEAN; ansi;BYTE (Though you may need to shorten those names to make it fit.) Note #1 - Access Flags. This consists of one byte; each of the eight bits corresponds to one flag. _________________________________ Flag #- | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | --------------------------------- Note #2 - Expert, Uppercase, and Clear Screen toggles are bytes that equal zero if that function is off, and one if the function is on. Note #3 - Last Read Pointers. Only the first 40 of these are used for last read pointers, the next six bytes after the initial 40 are the Board Select flags, and the last four bytes are not currently used. These pointers start at record offset $AD (173) and are composed of six bytes. The bits in each byte each correspond to a certain message base (a "1" value meaning that base is selected.) Board Select Pointer Format (read by UserEdit as three Integers) ------------------------------------ Record Offset: $AD/173 0 0 0 0 0 0 0 0 ---> 0 0 0 0 0 0 0 1 - values (unused) 36 31 26 21 16 11 6 1 - Base # $AF/175 0 0 1 0 0 0 0 1 ---> 0 0 0 0 0 0 0 0 - values 37 32 27 22 17 12 7 2 38 33 28 23 18 13 8 3 - Base # $B1/177 0 0 0 0 0 0 0 1 ---> 0 0 0 1 0 0 0 0 - values 39 34 29 24 19 14 9 4 40 35 30 25 20 15 10 5 - Base # In the above example, boards 1, 2, 4, 25, and 27 are selected. One other note about this field. The last integer (element #50) has been adopted by Craig Cross as a pointer to a record in a data file that is supported in his UEdit package. Note #4 - "ud"; there is no indication in RiBBS source code as to what this field is for. Maybe it means "undefined". Even Ron doesn't remember anything about this field. Note #5 - The terminal types are: 0-TTY, 1-ANSI, 2-OS-9. Message Base Files -==================- There are three files that makes up the RiBBS 2.02 message base. "TEXT", "IDX", and "HDR". - "TEXT" - This file is the typically the largest and is the simplest in structure of the three message base files. It is merely text data - there is no defined record length. Any attempt to make a diagram of the TEXT file here would simply confuse the reader, so I'll skip it. When file is first created it is empty (or simply filled with random garbage) and is as large as you ahave specified CreateMsg or PackMsg ("-s" option) to make it. When messages are posted or imported with MailImport, the "Currently Used Bytes" variable in HDR is accessed to find out how much of the TEXT file is full of active messages, then the program seeks that position (plus one byte) in TEXT and starts adding the new message (each line terminated by a conventional carriage return ($0D) character. - "HDR" - This file is unique in that it is both a variable length record file and a fixed length record file. Surely BASIC09 is one of the few languanges in existence that will allow this kind of flexibility in a file. I'll describe this file in two sections. Section #1 occupies the first 399 bytes of HDR and is the variable length record portion of the file... to put it more bluntly, it is a hodgepodge of variables and arrays which contains plenty of room for expansion. The format is as follows: Offset = HDR file - Section #1 = -------- _______________________________ $00/0 - | 2 bytes - unused | |-------------------------------| $02/2 - | Lowest Message Number (I) | |-------------------------------| $04/4 - | Highest Message Number (I) | |-------------------------------| $06/6 - | Number of Message Headers (I) | |-------------------------------| $08/8 - | # of bytes used in TEXT (R) | |-------------------------------| $0D/13 - | Maximum size of TEXT file (R) | |-------------------------------| $12/18 - | 2 bytes - unused | |-------------------------------| $14/20 - | Record # of first message for | ~ each of the 40 message bases. ~ | Array of 40 INTEGERS/80 Bytes | |-------------------------------| $64/100 - | 20 bytes - unused | |-------------------------------| $78/120 - | Record # of last message for | ~ each of the 40 message bases. ~ | Array of 40 INTEGERS/80 Bytes | |-------------------------------| $C8/200 - | 200 bytes - unused | |_______________________________| - End of Section #1 - _______________________________ $190/400 - | | | Start of Section #2 | \|/ \|/ Section #2 consists of the actual message headers, each of which contains information such as where each message starts (in the TEXT file), how long it is, who sent it, etc... Each record is 150 bytes long and there may be a maximum of 32,767 records (making the absolute maximum acceptible size of the HDR file 4,751,615 bytes long.) If you plan to manipulate the HDR file's records, be SURE to add 400 when SEEKing to a given record number since Record #1 starts at HDR file offset of $190 (400 decimal). Here is the format for each record: Record Offset Message Header Format ------------- _________________________________ $00/0 - | Board number (1-40) (B) | |---------------------------------| * $01/1 - | Number of Lines (0-32767) (I) | |---------------------------------| $03/3 - | Message # (1-32767) (I) | |---------------------------------| * $05/5 - | Zone (I) | <-| |---------------------------------| | $07/7 - | Net (I) | | |---------------------------------| |- Note #1 $09/9 - | Node (I) | | |---------------------------------| | * $0B/11 - | Point (I) | <-| |---------------------------------| $0D/13 - | Previous Reply Msg # (I) | <-| |---------------------------------| | $0F/15 - | Next Reply Msg # (I) | | |---------------------------------| |- Note #2 $11/17 - | Record # of previous Msg (I) | | |---------------------------------| | $13/19 - | Record # of next Msg (I) | <-| |---------------------------------| $15/21 - | Position in TEXT file where | | this message begins. (R) | |---------------------------------| $1a/26 - | Message Status Flags (F8) | <--- Note #3 |---------------------------------| $22/34 - | Person Message is "To" (S32) | |---------------------------------| $42/66 - | Person Message is "From" (S32) | |---------------------------------| $62/98 - | "Subject" of Message (S32) | |---------------------------------| $82/130 - | Date/Time message created (S20) | <--- Note #4 |_________________________________| ( * ) - Changed from v2.02 to v2.10 A typical Basic09 TYPE statement might look like: TYPE hdrformat=board:BYTE; lines,msgnum,zone,net,node,point,prep,nrep,pmsg, nmsg:INTEGER; startposs:REAL; flg(8):BOOLEAN; to,from,subj:STRING[32]; date:STRING[20] Note #1 - The "Zone"/"Net"/"Node"/"Point" fields contain a Fido style 4-ply address. If the message is Netmail posted on your system, the numbers in these fields correspond the the address you are sending the message to. So if you were sending a message to Fido Address 1:202/610, the Zone field would contain 1, the Net field would contain the value of 202, Node would contain 610, and Point would hold 0. If the message is a local or echo message posted on your system, then the values in net/node are ignored by RiBBS. If the message was imported by Mailimport, these fields contain the address of the system which physically sent your system the message (either your echo feed hub or, in the case of direct Netmail, the system the mail was posted on.) The exception to this is "Routed Netmail", where a net message was sent to your system via the echomail backbone. If this happens, then these fields should contain the address of the system the message was posted on, eventhough it was your echo hub which physically sent the message to your system. Using this information, RiBBS v2.10 and later can successfully allow you to respond to routed netmail and (using Wes Gale's latest Bundle program) you can even have the reply host-routed back to the sender (local policy restrictions may apply, however.) Note #2 - As you probably know by now, Message Numbers and Record Numbers do not always coincide (and usually don't except just after you run PackMsg with the renumbering option.) It is possible for the very first message (Record #1) to be Message #2 or #19 or #1000 or something. With this in mind, note that the fields for Next/Previous Reply Message # do not refer the the physical record number within the HDR file of the previous/next message; but the next two fields (Record # of previous/next message) do indeed refer to record numbers within HDR. Also, these pointers are "board specific". For example, for a message in Board #3, these four pointer values will reference the previous and next messages that also belong on Board #3. Note #3 - These eight boolean status flags are defined as follows: Flag #1 - TRUE = Message is Marked Flag #2 - TRUE = Message is Private Flag #3 - TRUE = Message has been read by recipient Flag #4 - TRUE = Message is Inbound FALSE = Message is Outbound Flag #5 - TRUE = There is a file-attach with this net message Flag #6 - reserved Flag #7 - FALSE = Outbound message has not yet been exported Flag #8 - TRUE = Message is flagged for deletion Flags #4 and #7 are relevant only for Netmail and Echo messages. Note #4 - The date format in this field is only critically important for messages which you plan to export later. In that case, the format must be "YY/MM/DD HH:MM:SS" (17 characters) terminated by an end-of-string character ($FF). That seems to be the format that the Export program expects to see them. Messages that you have -imported-, however, may use this format or the alternate "mailimport -d" format, which looks something like "YY/MM/DD (YY/MM/DD)", with the first date being the date the message was received on your system, the second date being the creation date of the message. - IDX - This file is merely a condensed version of the HDR file. Its purpose is to make high-speed message scanning faster. You can speed things up a great deal on the CoCo by using buffering techniques (loading several records at once and then doing your pattern matching within an array), so the smaller the records, the more you can read and buffer at one time. And since you really need little more than the recipient's name and a board number to figure out where a user's mail is, the IDX file is a good solution. The IDX file is built from scratch everytime PackMsg is run. The HDR file is read (record by record) and a smaller version of each record is written out to the IDX file. This file is also updated when a user posts a message or Mailimport imports mail. This, the IDX file will alway contain the same number of records that HDR does. Like the HDR file, the IDX file consists of two sections. Section #1 is 42 bytes long and the format is: Offset = IDX file - Section #1 = -------- ________________________________ $00/0 - | Lowest Message Number (I) | |--------------------------------| $02/2 - | Highest Message Number (I) | |--------------------------------| $04/4 - | Number of Message Headers (I) | |--------------------------------| $06/6 - | 36 bytes - unused | |________________________________| - End of Section #1 - ________________________________ $2B/43 - | | | Start of Section #2 | \|/ \|/ Again, Section #2 is one record for each message. Each record is 43 bytes long - the format looks like: Record Offset = IDX Ffile - Section #2 = ------------- __________________________________ $00/0 - | Board number (1-40) (B) | |----------------------------------| $01/1 - | Message # (1-32767) (I) | |----------------------------------| $03/3 - | Message Status Flags (F8) | <-- See Note #3 in the |----------------------------------| above HDR description $0B/11 - | Person message is "To" (S32) | |__________________________________| A typical Basic09 TYPE statement for this might look like: TYPE idxformat=iboard:BYTE; imsgnum:INTEGER; iflg(8):BOOLEAN; ito:STRING[32] RiBBS.CFG =========== "/DD/RiBBS.cfg" is the file that tells RiBBS "who it is", "what is where", and a number of other details. You can also have other copies of this file in different places on the drive and use that alternate filename in the command line when running RiBBSMain. This file is built by the program RConfig and its format looks like: Offset = RiBBS.CFG = -------- _______________________________________ $00/0 - | Pathname to: Fido Export Dir (S20) | $14/20 - | Message Base (S20) | $28/40 - | :::::::::::: Fido-In Area (S20) | $3C/60 - | System Data Area (S20) | $50/80 - | :::::::::::: Standard Data Path (S20) | $64/100 - | Log Full Pathname (S20) | $78/120 - | :::::::::::: UserIndex (S20) | $8C/140 - | Editor Temp Msg (S20) | $A0/160 - | :::::::::::: Opt. Local Editor (S20) | $B4/180 - | Menu Path (S20) | $C8/200 - | :::::::::::: Fido-Out Area (S20) | |---------------------------------------| * $DC/220 - | 40 bytes - unused | |---------------------------------------| * $104/260 - | Origin Address (S25) | |---------------------------------------| * $11D/285 - | Network Domain (S15) | |---------------------------------------| $12C/300 - | High Baud Rate (I) | |---------------------------------------| $12E/302 - | Fido Zone (I) | |---------------------------------------| $130/304 - | Node (I) | |---------------------------------------| $132/306 - | Net (I) | |---------------------------------------| $134/308 - | Point (I) | |---------------------------------------| $136/310 - | New User Level (I) | |---------------------------------------| $138/312 - | New User Flags (B) | |---------------------------------------| $139/313 - | New User Time Limit (B) | |---------------------------------------| $13A/314 - | New User Download Limit (B) | |---------------------------------------| $13B/315 - | Upload Ratio (Points) (I) | |---------------------------------------| $13D/317 - | Download Ration (Points) (I) | |---------------------------------------| $13F/319 - | Name Format 00=Full (B) | | 01=Open | |---------------------------------------| $140/320 - | Sysop Level (I) | |---------------------------------------| $142/322 - | Sysop Flags (B) | |---------------------------------------| $143/323 - | Message Scan 00=Disabled (B) | | 01=Prompted | | 05=Active | |---------------------------------------| $144/324 - | Edition number (I) | |---------------------------------------| $146/326 - | Applications 0=Not Accepted (I) | | 1=Accepted | |---------------------------------------| $148/328 - | CoCo [5] (outdated variable) (B) | |---------------------------------------| $149/329 - | I/O Pathname (S32) | |---------------------------------------| $169/361 - | Message Base Read Levels (I) | | Array of 40 elements - 80 bytes | |---------------------------------------| $1B9/441 - | Message Base Write Levels (I) | | Array of 40 elements - 80 bytes | |---------------------------------------| $209/521 - | Message Base Names (S20) | | Array of 40 elements - 800 bytes | |---------------------------------------| $529/1321 - | Message Base Status (B) | <--- Note #1 | Array of 40 elements - 40 bytes | |---------------------------------------| $551/1361 - | Color Palette Settings - Array (8B) | |---------------------------------------| $559/1369 - | Message Base/# of Days to Hold (I) | | Array of 40 elements - 80 bytes | |---------------------------------------| $5A9/1449 - | Forced Application 00=Yes (B) | | 01=No | |---------------------------------------| $5AA/1450 - | No Input Logoff (B) | |---------------------------------------| $5AB/1451 - | Modem Strings: Init (S40) | $5D3/1491 - | Hang-up (S40) | $5FB/1531 - | :::::::::::::: Busy (S40) | $623/1571 - | 9600 bps respon. (S40) | $64B/1611 - | :::::::::::::: 4800 " (S40) | $673/1651 - | 2400 " (S40) | $69B/1691 - | :::::::::::::: 1200 " (S40) | $6C3/1731 - | 300 " (S40) | $6EB/1771 - | :::::::::::::: Busy response (S40) | $713/1811 - | No Carrier rsp. (S40) | $73B/1851 - | :::::::::::::: No Connect rsp. (S40) | |---------------------------------------| $763/1891 - | Carrier Bit value (B) | |---------------------------------------| $764/1892 - | Carrier Call Code value (B) | |---------------------------------------| $765/1893 - | Display User Stat Screen TRUE=No (F) | | FALSE=Yes | |---------------------------------------| $766/1894 - | Login Delay (B) | |---------------------------------------| $767/1895 - | Connect Delay (B) | |---------------------------------------| $768/1896 - | Entry to BBS Message (S80) | |---------------------------------------| $7B8/1976 - | Message Base Origin Lines (S60) | | Array of 40 elements - 2400 bytes | |---------------------------------------| $1118/4376 | BBS Name (WaZoo "greeting") (S60) | |---------------------------------------| $1154/4436 | Sysop Name (S32) | |---------------------------------------| $1174/4468 | WaZoo Allowed? (TRUE/FALSE) (F) | |---------------------------------------| $1175/4469 | Serial number (R) | |_______________________________________| ( * ) - Changed from v2.02 to v2.10 Note #1 - The Message Base Status bytes are interpreted as a field of eight bits, each bit corresponding to a different state. The bit assignments are as follows: Bit - 7 6 5 4 3 2 1 0 - - - - - - - - | | | | | | | |_____ 0=Public / 1=Private | | | | | | |________ 1=Prompt for Private (bit-0=0) | | | | | |___________ unused | | | | |______________ unused | | | |_________________ unused | | |____________________ unused | |_______________________ 0=Local / 1=Echo |__________________________ 1=NetMail NODELIST.IDX ============== The NODELIST.IDX in your Fido-Out area is simply a "table of contents" for your Nodelist. It's format is very simple. Offset = Nodelist.IDX = -------- _______________________________________________ $00/0 - | Filename of current NODELIST.XXX file (S12) | |-----------------------------------------------| $0C/12 - | Zone (I) | Net (I) | PosM (I) | PosL (I) | <- Record #1 |-----------+-----------+-----------+-----------| $14/20 - | Zone (I) | Net (I) | PosM (I) | PosL (2) | <- Record #2 |-----------+-----------+-----------+-----------| \|/ \|/ \|/ \|/ \|/ etc, etc.... The program "Nodeprocess" scans the NODELIST.xxx file and builds the Nodelist.IDX file. Each time, it sees a line that starts with "Zone,", "Region," or "Host," it writes a record out to the Nodelist.IDX noting position in the NODELIST.XXX file where that line starts. PosM = Most significant word of position. PosL = Least significant word of the position. therefore.... Position = (PosM*65536)+PosL (Note: Beware of Basic09's tendency to interpret integers larger than 32767 as negative numbers.) Menus ======= - MENU.LIST - This file is pretty simple in structure. Each record is 92 bytes long and formated as: Record Offset = MENU.LIST = --------------- _________________________________ $00/0 - | Menu Option Text (S80) | |---------------------------------| $50/80 - | Menu Option Pathname (S12) | |_________________________________| | | \|/ \|/ Example TYPE statement: TYPE menu_list=mntext:STRING[80]; mnpath:STRING[12] The Menu Option Text is the part of the menu that the user sees. If the last character of the string is a ";" character, no carriage return will be issued after that line is displayed. The Menu Option Pathname is only used with menu options that involve running a module or accessing a file and contains the name/pathname of that module/ file. Each full menu consists of 40 of these records (whether all 40 are used or not.) Therefore, if you want to find the start point of a particlar menu, calculate: Seek_position = (record_size * 40) * (desired_menu_number - 1) - MENU.LVL - Each record in the MENU.LVL file is 5 bytes long and looks like: Record Offset = MENU.LVL = -------------- __________________________________ $00/0 - | Menu Option Action Code (B) | |----------------------------------| $01/1 - | Menu Option Access Flags (B) | |----------------------------------| $02/2 - | Menu Option Letter (S1) | |----------------------------------| $03/3 - | Menu Option Access Level (I) | |__________________________________| | | \|/ \|/ Example TYPE statement: TYPE menu_level=mnact,mnflg:BYTE; mnltr:STRING[1]; mnacc:INTEGER Again, each menu takes up 40 of these records and you would use the same kind of formula mentioned in the previous section to calculate where to SEEK to find the desired menu's data. MailImport Stats ================ - MiStat.DAT - The purpose of this file (which is created when using the "-S" options with MailImport) is to provide some raw data to a statistics program that keeps track of how much mail was recieved, etc... (such programs are rampant in the IBM world.) This (optional) file resides in your BBS working directory. If the file does not exist, Mailimport will create it. If the file has no records in it, it will be deleted when Mailimport exits. An existing mistat.dat file will be appended to and will continue to grow until you or another program deletes it. The idea here is for a statistics manager program to run periodically to process this data, then delete this file. This could be done once per Fido session, per day, per week, or even presumably once per month before overfragmentation prevents it being added to. The last record in the file will always contain the results of the last mail run. Record Offset = MiStat.DAT = ------------- _________________ $00/00 - | Zone (I) | --\ |----------------| \ $02/02 - | Net (I) | >-- System mail was received from |----------------| / $04/04 - | Node (I) | --/ |----------------+--------------------------------- $06/06 - | Mail Processing Start Date/Time S(17) | |--------------------------------------------------| $17/23 - | "" "" End Time S(8) | |--------------------------------------------------| $1E/30 - | High Record in HDR when MailImport started (I) | <- Note #1 |--------------------------------------------------| $70/112 - | Number of messages processed per board 40x(I) | <- Note #2 |--------------------------------------------------| | $C0/192 - | Size of all messages processed per board 40x(R) | <- Note #2 |__________________________________________________| Exmaple TYPE statement: TYPE mstats=szone,snet,snode:INTEGER; stime:STRING[17]; etime:STRING[8]; snum,smsg(40):INTEGER; ssize(40):REAL Note #1 - In cases where Mailimport finds mail from more than one system, it will process only one system's mail (skipping the other .PKT files), save out a record to "mistat.dat", then go back to process the other system(s) mail. The "High Record in HDR" will not change even if two or more records are written out in one session. This is intentional and make things easier for those writing programs to scan the HDR files for new records after Mailimport is finished. Note #2 - These two arrays contain the number of messages and the total bytecount for messages in each of the 40 message bases. The array element number points to its respective board number. Passwords ========= - Password.CTL - RiBBS 2.10 has an entirely new Password.CTL file format. It should be sufficient for quick access and future expansion. The records do not have to be in numerical order by Zone/Net:Node for current programs (like Mailimport or Bundle) to process it correctly, but if you add/delete entries to this file, it is strongly suggested that you follow RBPass' example and keep them sorted - just in case that becomes a future requirement. The records are structured like this: Record Offset = Password.CTL = --------------- _________________________________ $00/00 - | Zone (I) | |---------------------------------| $02/02 - | Net (I) | |---------------------------------| $04/04 - | Node (I) | |---------------------------------| $06/06 - | Session Level Password (S8) | |---------------------------------| $0E/14 - | Packet Level Password (S8) | |---------------------------------| $16/22 - | AreaFix Password (S8) | |---------------------------------| $1E/30 - | reserved for expansion (S8) | |_________________________________| Example TYPE statement: TYPE password=pzone,pnet,pnode:INTEGER; pw1,pw2,pw3,pw4:STRING[8] Password.CTL is fixed at exactly 100 records (3,800 bytes). There must be no blank entries until after the last real entry since some (if not all) programs that read this file assume they have read the last entry when they get a Zone:Net/Node address of "0:0/0". Also, the password fields themselves MUST be null padded to their full length (no $FF string terminators allowed.) This can be tricky in BASIC09 if you aren't paying attention to what you are doing. Stat ==== The "STAT" file is kept in your main BBS work directory. I won't be including a type statement here, since this file is typically just opened and updated one field at a time. This file serves mainly as a scratchpad for the BBS, aiding in keeping track of events, schedules, and settings. Offset = STAT = -------- ________________________________________ $00/00 - | Current I/O Path (I) | <- Note #1 |--------------------------------------| $02/02 - | Today's Date (S20) | |--------------------------------------| $16/32 - | Last Caller (S32) | |--------------------------------------| $36/54 - | Total Calls to BBS (R) | |--------------------------------------| $3B/59 - | New User Calls Today (R) | |--------------------------------------| $40/64 - | Fido Calls since last Startup (R) | |--------------------------------------| $45/69 - | Number of Calls Today (R) | |--------------------------------------| $4A/74 - | Not used? (S6) | <- Note #2 |--------------------------------------| $50/80 - | Time Last Event was Processed (S17) | |--------------------------------------| $61/97 - | Outbound Mail Enable (F) | |--------------------------------------| $62/98 - | Chat Enable (F) | |--------------------------------------| $63/99 - | 300 Baud Acceptance Enable (F) | |--------------------------------------| $64/100 - | Human Caller Acceptance Enable (F) | |--------------------------------------| $65/101 - | Current Schedule Number (S1) | <- Note #3 |______________________________________| Note #1 - This records contains the same information as the "la.ad1" variable mentioned in the "Outside Program Format" section below. When running a multi-line system, this setup can cause some conflict if you have both copies of the BBS sharing the same work directory (and hence, the same STAT file.) Note #2 - I could find no instance in RiBBS of this area being read or written to. Note #3 - This field contains the ASCII representation of the current Schedule number (i.e. "1", "2", etc...) therefore only numbers up to "9" are acceptible. ==------------------------== Ouside Program Format ======================= What follows is an editted version of files Ron Bihler released long ago that reveal what you need to know to write modules that RiBBS can call with a Menu Action #11 call. Have your program start with the following code. TYPE address=ad1,ad2,ad3,ad4,local:INTEGER PARAM la:address PARAM name$:STRING[32] PARAM level:INTEGER PARAM timelimit:INTEGER PARAM ontime$:STRING[14] PARAM cls,cr:STRING[3] PARAM case$:STRING[1] PARAM info(12):STRING[32] la.ad1 - contains path number presently opened for IO. la.ad2 - used by system la.ad3 - Contains the TERM TYPE 0=No ansi 1=ANSI 2=OS/9 codes. la.ad4 - is the page length setting at present. 0 = disabled la.local - 0 or 1 depending on whether ribbs is in local mode or not name$ - is the present users name level - is the users secrutity level timelimit - contains the users timelimit for this call ontime - contains the time the user logged on cls - is the code sequence to clear users screen. case$ - L for lower case U for upper case. info - info for the use of dumpfile. ------------------- Use of "Elapsed" to get the amount of time a user has been on: RUN elapsed(la,ontime,elapsedtime) la : same as above Ontime : same as above Elapsedtime : REAL (* Time the user has been on the system. Now, to find out if a user has overstayed his welcome, you can simply (after running "elapsed") subtract "elapsedtime" from "Tlimit"... if you get a value less than one, the user has exceeded his time limit. ----------------- Use of "CDCheck" to check the status of the modem carrier: RUN cdcheck(la,cd) la : same as above cd : BYTE If after running "cdcheck", the value of "cd" is non-zero, carrier has been lost. ----------------- Use of "Dumpfile" to display a file to the user: RUN dumpfile(la,filename,case$,info,ac) la : same as above filename : STRING[80] (* contains full pathname if needed case : same as above info : same as above ac : BYTE (* used by system Some Info Data 1. City,State 2. Download Limit 3. ElapsedTime 4. Flags 5. timelimit 6. Last Person On, (Before this user) 7. Date$ 8. 9. Number of Calls User has made to system 10 Level 11. Last Day user Called 12. Users Name -------------------- Use of "Linein" to get input from the user: RUN linein(la,case,b$,wnum,wrap) la : same as above case : same as above b$ : STRING[160] (* Input Line wnum : byte When entered is the current posstion of the cursor (i.e. if b$="1 [" then wnum=3 (or 0 if word-wrap is off.)) When Linein is exitted, it will contain the last character before the word was wrapped. In most cases, this will be the last "space" character in the line (before it wrapped the last word.) wrap : Byte Zero for Word Wrap Off. Or is the Max size of the line to be entered. ------------------- Use of "Numin" to get numeric input from the user: RUN numin(la,b$,innum) la : same as above b$ : STRING[160] Prompt text (i.e. b$="What is your Age:") innum : REAL Returns with number input by user ------------------- Use of "Onekey" to get single key entry from the user. RUN onekey(la,a$,ac) la : same as above a$ : STRING[1] Contains keypress by user ac : BYTE ASCII value of keypress ("The module "Charin" works the same except that the character is not echoed back to the user or the local screen.) ------------------- Use of "Lineout" to send an output line to the user: RUN lineout(la,b$,case) la : same as above b$ : STRING[160] (* Output Line case : same as above ------------------ Use of "Charout" to send one character to the remote user. RUN charout(la,a$,cd) la : same as above a$ : STRING[1] Byte to send to user cd : BYTE Like CDCheck, Charout checks for carrier status and returns the value in this param. ==--------------------------== Most programmers find it useful to have subroutines that run Linein and Lineout - then have each of those subroutines call yet another subroutine that calls CDCheck and Elapsed. This way, there is a check for carrier and time limit each time someting is output to a user or he/she is prompted for input. Running RiBBS Modules ======================= I'll not try to describe how to run Editor or PutMsg here. The RiBBS 2.02 distribution package contains the source code to a program called CREATEMSG. It is heavily commented and is an extremely good example of exactly how one can insert text into the message base and call the editor. I don't intend to document ALL RiBBS modules here - just those that seem to be modules that someone may wish to run from modules of their own. - Application - This program is either run from a menu option or from RiBBS when the RConfig option for Forced Applications is set to "On". It's called like this: RUN application(la,name,level,tlimit,tsave,cls,cr,case$,filename,flags) - Chat - This program is called when the user pages you for chatting, or the sysop involks the mode with the ALT-C sequence. For those wishing to write new versions of the chat module, it will be called from RiBBSmain like this: RUN chat(la,name,a$,cls,cr,chat,tlimit,ontime) - Fileout - This module is what gives your users a menu of available protocols and prompts them for filenames that they wish to download. The format IS different from v2.02 to v2.10. It is called like this: RUN Fileout(la,name,dlimit,pathname,ontime,tlimit,cr,cls,case$,accum,info, filename,proto,lover,drv5,rbaud) - Upload - This module accepts user uploads, prompts for descriptions, and updates Files.BBS and Desc.BBS. Several unused parameters have been removed in the v2.10 version. RUN Upload(la,name,case$,cls,cr,drv5,drv7,ontime,level,tlimit,pathname,accum, co,baud,info) = Descriptions of Parameters = Variable Type Description ========== ============ =================================================== a$ STRING[1] -When passed to "Chat", it contains "U" or "L" to specify whether the user can handle lowercase. "Chat" exits back to RiBBSMain with a$ containing "Y" to indicate that the sysop answered the page, "N" if he/she did not. accum acc -(see note #1 on "acc" variable type below) baud INTEGER -User's baud rate - Upload passes this to XMin case$ STRING[1] -"L" for lowercase, "U" for no lowercase chat BOOLEAN -TRUE if Chat status is active, FALSE if not cls STRING[3] -The ASCII sequence to clear the user's screen co(8) STRING[3] -The OS-9 foreground color sequences cr STRING[3] -The ASCII sequence to issue carriage return dlimit BYTE -User's current online download limit. This variable gets decremented by Fileout for each successful file transferred in a call. drv5 STRING[20] -Path to the system Log file drv7 STRING[20] -Temporary Editor path filename STRING[80] -This parameter will have a filename in it if Fileout was run by "Browse" or something similar. Also, for "Application" this variable equals the the name of the applicaton script file (i.e. "New2.asc") flags BYTE -The user's access flags (see the Userlog section) info(12) STRING[32] -(see description in Outside Program Format section) la address -(see description in Outside Program Format section) level REAL -User's access level. Upload passes this to Editor lover BYTE -Equals 1 if Fileout was run by "Browse" after the user selected the "[L]ist" option. name STRING[32] -Name of the user online ontime STRING[14] -The time that the user logged on. Used by Elapsed pathname STRING[80] -Pathname to the current download directory proto BYTE -The protocol number that the user selected last. This variable is set to zero before the first download. * rbaud INTEGER -True baud rate of the remote modem. tlimit INTEGER -The number of minutes a person has left online "Upload" updates this variable so that the user is penalized for upload time. tsave INTEGER -User's permanent time limit. After Application modifies this variable it is unchanged by RiBBSMain and is saved to the Userlog when the user logs off. ( * ) - New v2.10 parameter Note #1 - The "acc" variable type contains several values that pertain to the download points/limits/totals fields in the userlog. The TYPE statement to define this variable is: TYPE acc=dw,up:BYTE ku,kd,ms,pt,urate,drate:INTEGER Variable Description ========== ================================================================ dw -The number of files downloaded. "Fileout" adds to a user's total for each successful transfer. up -The number of files uploaded. "Upload" adds to a user's total for each successful submission. ku -The number of Kbytes uploaded. "Upload" adds to this. kd -The number of Kbytes downloaded. "Fileout" adds to this. ms -Used by the system. "Upload" and "Fileout" do not reference this variable. pt -The user's number of accumulated download points. Both Upload and Fileout update this field. urate -The system Upload Ratio (set in RConfig). If zero, the points system is bypassed (except that "pt" continues to be updated.) drate -The system Download Ration (set in RConfig). This is how much download credit (in points) you allow new users. In closing... ================= This file will probably see some changes in the not-so-distant future as more information is needed by you RiBBS developers and as I change some of these formats in future versions of RiBBS. I hope that the information here will go a long way toward encouraging you to write your own support programs for the rest of us to share. Please alert me to any inaccuracies you may find in this document, this may save some other poor (and less observant) soul from certain doom. (grin) -Charles West Arrakis BBS / RiBBS Headquarters 300 - 9600 bps (v32/v42bis) (405) 752-8955 -- (1:147/61.0) DELPHI: SANDRIDER -eof-