Contents of the READMSGS.DOC file
An example of BASIC file handling in C for RBBS-PC.
READMSGS is a simple program to demonstrate how BASIC random access files
can be accessed in C. The program will read the MESSAGES file (you
either supply the filename on the command line, or the program asks for a
file name) and display checkpoint and node record files. Only the
author's laziness prevents the program from also reading message header
and text records.
The problems that arise from reading BASIC files in C are not difficult
to overcome. The worst problem is that BASIC does not terminate strings
with NULL's, so handling strings can be tricky. It may be tedious, but
it CAN be done! Accessing the data itself is not a problem, in that C
has a more powerful I/O handler. The BASIC FIELD statement is mimiced in
the form of a union of structures. This union is also used as a record
buffer. Getting the data in the buffer is a simple fread() command.
Positioning the file may take more work than BASIC, but I can stand the
inconvenience. Instead of passing a record number to the read command,
you must pass the byte offset. This is a simple calculation of
RECORD_NUMBER * RECORD_LENGTH. The OPTION_BASE is even taken into
consideration for those who are used to record 0 or record 1 being the
Once the data is in the buffer, you can extract each field for use.
Integers that are saved as integers can be handled directly (too bad
RBBS-PC doesn't do this!). Integers
that were saved as character strings (a ghastly idea!) must be handled
more carefully. In the program you will find an example of a conversion
of this type. The character string is first copied to a temporary
string, and a NULL is appended so C can recognize the string. A call to
atoi() will produce a true integer.True strings should be handled in
the same way (appending a NULL), and for BASIC compatibility these NULL's
should be removed (replaced with ' ') before writing data to the file.
The code is not elegant, but it does attempt to show off some of C's
capabilities. The union of structures was used to show how C can handle
multiple FIELD statements concurrently. The read_rec() function treats
this union like a character buffer, completely ignoring the union. The
show_user_rec() function uses both structures in the union.Another
function may only use one structure, and would not need to declare the
union at all. Some consider this confusing, others say it's powerful.
The only warning you MUST heed is to PACK your STRUCTURES! By default, C
aligns each element of a structure on a word boundary. Since the
structure is treated like a buffer, the entire structure MUST be
contiguous!By packing structures, we sacrifice a little speed, but we
gain power.The compiler switch for packing structures is /Zp for the
Microsoft C compiler.
For utility programmers, writing in C for the current RBBS-PC system will
mean developing a library of routines that will LSET, CVI, MKI$, etc.
This is NOT difficult! If RBBS-PC is ported to C, THIS programmer would
do everything possible to improve the data structures and make them
easier to use in C (or other languages).
With the announcement of the Microsoft 'Quick C' compiler, the time may
have come to convert programs like RBBS-PC to C. We would gain greater
compiler power, code could be truly modular, and interfaces into other
products (database managers, hardware devices) would be easier to manage.
Besides, the world needs more C programmers, and RBBS-PC has already
helped fill the world with BASIC programmers!
of the Palm Beaches, Inc.
P.O. Box 31024
Palm Beach Gardens, Fl 33410
VOICE: (305) 627-9767
DATA: (305) 627-6969
NOTE: This document and the accompanying code were produced as a
tutorial on BASIC to C file I/O conversion.The author grants you the
right to distribute, modify and use this program as long as:
1) NO FEE is charged for its use or distribution
2) Acknowledgement is given as to the source of the program.
You may incorporate all or part of this program into another product, as
long as the final product meets the above restrictions.
NOTE: Due to errors in the RBBS-PC documentation, I am appending a
corrected version of the record layouts.
The FIRST RECORD of the "MESSAGES" file acts as a "checkpoint" record for
all the multiple RBBS-PC's that may be sharing the MESSAGES and USERS
files.It contains information critical to maintaining the integrity of
these two files. The layout of RBBS-PC Message File Record Number 1 is
Position Length Description
1 - 8 8 Number of last message on system
9 - 10 2 --- RESERVED FOR FUTURE USE ----
11 - 20 10 Current caller number
21 - 51 31 --- RESERVED FOR FUTURE USE ----
52 - 56 5 Record Number of first record in the USERS file
57 - 61 5 Record Number of the next available record in the
62 - 66 5 Record Number of the last record in the USERS file
67 1 Reserved for Node ID currently reserving the USERS file
68 - 74 7 Record Number where "messages" portion of the
MESSAGES file begins
75 - 81 7 Record Number of the next available record in the
MESSAGES file where the next message may be written
82 - 88 7 Record Number of the last record in the MESSAGES file
89 - 95 7 Maximum number of messages allowed in the MESSAGES file
96 - 97 2 Reserved for Node ID currently reserving the MESSAGES file
98 -122 25 --- RESERVED FOR FUTURE USE ----
123 -126 4 Last message number read by the SYSOP
127 -128 2 Maximum number of RBBS-PC's sharing this MESSAGES file
Following the first record of the MESSAGES file are from one to 36 "node"
records. Each "node" record contains information critical to the
running of that copy of RBBS-PC associated with that "node". The layout of
each RBBS-PC "node" record is as follows:
Position Length Description
1 - 31 31Name of last person on this copy of RBBS-PC
32 - 33 2Available indicator for SYSOP
34 - 35 2Annoy indicator for SYSOP
36 - 37 2Indicator that the SYSOP is next on the system
38 - 39 2Line printer available indicator
40 - 41 2Door's availability indicator
42 - 43 2Eight bit transmission indicator
44 - 45 2Baud rate. -1 = 300, -2 = 450, -3 = 1200, -4 = 2400
46 - 47 2Upper case indicator
48 - 52 5---- RESERVED FOR FUTURE USE ----
53 - 54 2Graphics indicator
55 - 56 2SYSOP indicator
57 1Activity indicator (I=inactive, A=active)
58 - 59 2SNOOP indicator
60 - 63 4Baud rate caller dialed in at. 300, 1200, 2400
64 - 69 8Time logged on system
72 - 73 2Private Door
74 - 75 2Transfer Function
76 - 85 10Daily Exit Last Date
86 - 90 5Daily Exit Last Time
91 - 92 2Reliable Mode
93 - 128 36---- RESERVED FOR FUTURE USE ----
A message within the messages file consists of a MESSAGE HEADER followed by
the text of the message. The RBBS-PC Message File "message header" record
layout is as follows:
Position Length Description
1 1Contains an "*" for read-only messages, blank otherwise
2 - 5 4Message number of this message
6 - 36 31The name of the person the message is from
37 - 58 22The name of the person to whom the message is sent
59 - 66 8Time of day that the message was sent (HH:MM:SS)
67 - 67 1---- RESERVED FOR FUTURE USE ----
68 - 75 8Date the message was sent (MM-DD-YY)
76 -100 25Subject of the message
101 -115 15Password for the message (if any)
116 -116 1"Active" message indicator = hex 225
"Killed" message indicator = hex 226
117 -120 4Number of 128-byte records for this message --
including the the "message header" record.
121 -122 2 ---- RESERVED FOR FUTURE USE ----
123 -125 3 Date (packed) the message was last read (MM/DD/YY)
126 -128 3 Time (packed) the message was last read (HH:MM:SS)
Each record following the MESSAGE HEADER record is a MESSAGE TEXT record
and consists of 128 characters. Each of these 128-byte message text"
records contains the message text. The end of each line in the message is
followed byan RBBS-PC "end-of-line" indicator which is equal to
an ASCII 227. This allows RBBS-PC to "pack" multiple message lines in a
single 128-byte record.