- hack.doc for Citadel/UX
- written by Art Cancro (ajc@uncnsrd.mt-kisco.ny.us)
+ hack.txt for Citadel/UX
+ (some of this stuff is *very* out of date.)
Much of this document is borrowed from the original hack.doc from
Citadel-CP/M and Citadel-86, because many of the concepts are the same. Hats
Implementing the "new message" function is also trivial in principle:
we just keep track, for each caller in the userlog, of the highest-numbered
-message which existed on the >last< call. (Remember, message numbers are
+message which existed on the *last* call. (Remember, message numbers are
simply assigned sequentially each time a message is created. This
sequence is global to the entire system, not local within a room.) If
we ignore all message-numbers in the room less than this, only new messages
will be printed. Voila!
-
+
+
Message format on disk (MSGMAIN)
- Each message begins with an FF byte. The next byte will then be MES_NORMAL,
-MES_ANON, or MES_ANON2, depending on whether the message in anonymous or not.
-The next byte is either a 0 or 1. If it is 0, the message will be printed
-with the Citadel formatter. If it is a 1, the
-message is printed directly to the screen, as is. External editors generate
-this type of message. After these three opening bytes, the remainder of
+ As discussed above, each message begins with an FF byte.
+
+ The next byte denotes whether this is an anonymous message. The codes
+available are MES_NORMAL, MES_ANON, or MES_AN2 (defined in citadel.h).
+
+ The third byte is a "message type" code. The following codes are defined:
+ 0 - "Traditional" Citadel format. Message is to be displayed "formatted."
+ 1 - Plain pre-formatted ASCII text (otherwise known as text/plain)
+ 4 - MIME formatted message. The text of the message which follows is
+ expected to begin with a "Content-type:" header.
+
+ After these three opening bytes, the remainder of
the message consists of a sequence of character strings. Each string
begins with a type byte indicating the meaning of the string and is
ended with a null. All strings are printable ASCII: in particular,
BYTE Mnemonic Comments
-# Local ID A 32-bit integer containing the message ID on the
- system the message is *currently* on (obviously this
- is meaningless for a message being transmitted over
- a network).
A Author Name of originator of message.
-B Phone number The dialup number of the system this message
- originated on. This is optional, and is only
- defined for helping implement C86Net gateways.
D Destination Contains name of the system this message should
be sent to, for mail routing (private mail only).
-G Gateway domain This field is provided solely for the implementation
- of C86Net gateways, and holds the C86Net domain of
- the system this message originated on. Unless you're
- implementing such a gateway, there's no need to even
- bother with this field.
+E Extended 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
+ message should be deleted. If there exist any messages
+ with the same Extended 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.
H HumanNodeName Human-readable name of system message originated on.
I Original ID A 32-bit integer containing the message ID on the
system the message *originated* on.
N Nodename Contains node name of system message originated on.
O Room Room of origin.
P Path Complete path of message, as in the UseNet news
- standard. A user should be able to send UUCP mail to
- this path. (Note that your system name will not be
+ standard. A user should be able to send Internet mail
+ to this path. (Note that your system name will not be
tacked onto this until you're sending the message to
someone else)
R Recipient Only present in Mail messages.
network. Usually means that the message isn't really
a message, but rather some other network function:
-> "S" followed by "FILE" (followed by a null, of
- course) means that the message text is actually an
- IGnet/Open file transfer.
+ course) means that the message text is actually an
+ IGnet/Open file transfer.
+ -> "S" followed by "CANCEL" means that this message
+ should be deleted from the local message base once
+ it has been replicated to all network systems.
T Date/Time A 32-bit integer containing the date and time of
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
not generate them, but it does print them when found.
-X eXtension field Extension fields are used to carry additional RFC822
- type lines. X fields contain the X byte followed by
- the RFC822 field name, a colon, a space, and the value.
-Z Separator If there are MIME attachments following the message
- text, the Z field specifies the separator string.
+0 Error This field is typically never found in a message on
+ disk or in transit. Message scanning modules are
+ expected to fill in this field when rejecting a message
+ with an explanation as to what happened (virus found,
+ message looks like spam, etc.)
EXAMPLE
cycling under control.
(Uncoincidentally) the format used to transmit messages for networking
-purposes is precisely that used on disk, except that there may be any amount
-of garbage between the null ending a message and the <FF> starting the next
-one. This allows greater compatibility if slight problems crop up. The current
-distribution includes netproc.c, which is basically a database replicator;
+purposes is precisely that used on disk, serialized. The current
+distribution includes serv_network.c, which is basically a database replicator;
please see network.txt on its operation and functionality (if any).
Portability issues
- At this point, most hardware-dependent stuff has been removed from the
-system. On the server side, most of the OS-dependent stuff has been isolated
-into the sysdep.c source module. The server 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.
+ Citadel/UX 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.
On the client side, it's also POSIX compliant. The client even seems to
-build ok on non-POSIX systems with porting libraries (such as the Cygnus
-Win32 stuff).
+build ok on non-POSIX systems with porting libraries (such as Cygwin).
"Room" records (quickroom)
char QRpasswd[10]; /* Only valid if it's a private rm */
long QRroomaide; /* User number of room aide */
long QRhighest; /* Highest message NUMBER in room */
- char QRgen; /* Generation number of room */
+ long QRgen; /* Generation number of room */
unsigned QRflags; /* See flag values below */
char QRdirname[15]; /* Directory name, if applicable */
char QRfloor; /* (not yet implemented) */
SUPPORTING PRIVATE MAIL
-Can one have an elegant kludge? This must come pretty close.
-
-Private mail is sent and recieved in the Mail> room, which otherwise
-behaves pretty much as any other room. To make this work, we store
-the actual message pointers in a message list for each user (MAILBOXES)
-instead of MSGLISTS. This requires a little fiddling to get things just
-right. We have to update quickroom[1].QRhighest at login
-to reflect the presence or absence of new messages, for example. And
+ Can one have an elegant kludge? This must come pretty close.
+
+ Private mail is sent and recieved in the Mail> room, which otherwise
+behaves pretty much as any other room. To make this work, we have a
+separate Mail> room for each user behind the scenes. The actual room name
+in the database looks like "0000001234.Mail" (where '1234' is the user
+number) and it's flagged with the QR_MAILBOX flag. The user number is
+stripped off by the server before the name is presented to the client.
+
+ This requires a little fiddling to get things just right. For example,
make_message() has to be kludged to ask for the name of the recipient
of the message whenever a message is entered in Mail>. But basically
it works pretty well, keeping the code and user interface simple and