------------------------------------------------------
- The totally incomplete guide to Citadel/UX internals
+ The totally incomplete guide to Citadel internals
------------------------------------------------------
Citadel has evolved quite a bit since its early days, and the data structures
by Citadel. Here are some of the tables we keep on disk:
- USERSUPP
- --------
+ USER RECORDS
+ ------------
- This table contains all user records. It's called 'usersupp' because it was
-once a supplementary file (at one point in ancient history, we created a user
-record on the underlying operating system for each user). It's indexed by
+ This table contains all user records. It's indexed by
user name (translated to lower case for indexing purposes). The records in
this file look something like this:
-struct usersupp { /* User record */
+struct ctdluser { /* User record */
int version; /* Cit vers. which created this rec */
uid_t uid; /* Associate with a unix account? */
- char password[32]; /* password (for BBS-only users) */
+ char password[32]; /* password (for Citadel-only users)*/
unsigned flags; /* See US_ flags below */
long timescalled; /* Total number of logins */
long posted; /* Number of messages posted (ever) */
information so we set it up dynamically.
- QUICKROOM
- ---------
+ ROOM RECORDS
+ ------------
- These are room records. One per room. It's called 'quickroom' because at
-one time it was a quick index hash type of thing (there was a pair called
-quickroom and fullroom). There is a quickroom record for every room on the
+ These are room records. There is a room record for every room on the
system, public or private or mailbox. It's indexed by room name (also in
lower case for easy indexing) and it contains records which look like this:
-struct quickroom {
+struct ctdlroom {
char QRname[ROOMNAMELEN]; /* Name of room */
char QRpasswd[10]; /* Only valid if it's a private rm */
long QRroomaide; /* User number of room aide */
to prevent duplicates from being posted if someone misconfigures the network
and a loop is created. This table goes unused on a non-networked Citadel.
- MSGMAIN
- -------
+ THE MESSAGE STORE
+ -----------------
This is where all message text is stored. It's indexed by message number:
give it a number, get back a message. Messages are numbered sequentially, and
BYTE Mnemonic Comments
A Author Name of originator of message.
+B Big message This is a flag which indicates that the message is
+ big, and Citadel is storing the body in a separate
+ record. You will never see this field because the
+ internal API handles it.
D Destination Contains name of the system this message should
be sent to, for mail routing (private mail only).
-E Extended ID A persistent alphanumeric Message ID used for
+E Exclusive ID A persistent alphanumeric Message ID used for
network replication. When a message arrives that
- contains an Extended ID, any existing messages which
- contain the same Extended ID and are *older* than this
+ contains an Exclusive ID, any existing messages which
+ contain the same Exclusive ID and are *older* than this
message should be deleted. If there exist any messages
- with the same Extended ID that are *newer*, then this
+ with the same Exclusive ID that are *newer*, then this
message should be dropped.
F rFc822 address For Internet mail, this is the delivery address of the
message author.
the message in standard UNIX format (the number
of seconds since January 1, 1970 GMT).
U Subject Optional. Developers may choose whether they wish to
- generate or display subject fields. Citadel/UX does
+ generate or display subject fields. Citadel does
not generate them, but it does print them when found.
0 Error This field is typically never found in a message on
disk or in transit. Message scanning modules are
Let <FF> be a 0xFF byte, and <0> be a null (0x00) byte. Then a message
which prints as...
-Apr 12, 1988 23:16 From Test User In Network Test> @lifesys (Life BBS)
+Apr 12, 1988 23:16 From Test User In Network Test> @lifesys (Life Central)
Have a nice day!
might be stored as...
<FF><40><0>I12345<0>Pneighbor!lifesys!test_user<0>T576918988<0> (continued)
-----------|Mesg ID#|--Message Path---------------|--Date------
-AThe Test User<0>ONetwork Test<0>Nlifesys<0>HLife BBS<0>MHave a nice day!<0>
+AThe Test User<0>ONetwork Test<0>Nlifesys<0>HLife Central<0>MHave a nice day!<0>
|-----Author-----|-Room name-----|-nodename-|Human Name-|--Message text-----
Weird things can happen if fields are missing, especially if you use the
Portability issues
- Citadel/UX is 64-bit clean, architecture-independent, and Year 2000
+ Citadel is 64-bit clean, architecture-independent, and Year 2000
compliant. The software should compile on any POSIX compliant system with
a full pthreads implementation and TCP/IP support. In the future we may
try to port it to non-POSIX systems as well.
This has changed a couple of times over the course of Citadel's history. At
this point it's very simple, again due to the fact that record managers are
-used for everything. The user file (usersupp) is indexed using the user's
+used for everything. The user file (user) is indexed using the user's
name, converted to all lower-case. Searching for a user, then, is easy. We
just lowercase the name we're looking for and query the database. If no
match is found, it is assumed that the user does not exist.