As previously noted, many commands implicitly reference the room the user is in. Here is how to move to another room:
This command is used to goto a new room. When the user first logs in (login is completed after execution of the PASS command) this command is automatically and silently executed to take the user to the first room in the system (usually called the Lobby).
This command can be passed one or two parameters. The first parameter is, of course, the name of the room. Although it is not case sensitive, the full name of the room must be used. Wildcard matching or unique string matching of room names should be the responsibility of the client.
Note that the reserved room name “_BASEROOM_” can be passed to the server to cause the goto command to take the user to the first room in the system, traditionally known as the Lobby>. As long as a user is logged in, a GOTO command to _BASEROOM_ is guaranteed to succeed. This is useful to allow client software to return to the base room when it doesn't know where else to go.
There are also several additional reserved room names:
|_MAIL_||goes to the user's inbox (i.e. the Mail> room).|
|_TRASH_||goes to the user's personal trashcan room (trash folder).|
|_BITBUCKET_||goes to a room that has been chosen for messages without a home.|
|_CALENDAR_||goes to the user's primary personal calendar.|
|_CONTACTS_||goes to the user's primary personal address book.|
|_NOTES_||goes to the user's primary personal notes room.|
|_TASKS_||goes to the user's primary personal task list.|
The second (and optional) parameter is a password, if one is required for access to the room. This allows for all types of rooms to be accessed via this command: for public rooms, invitation-only rooms to which the user has access, and preferred users only rooms to which the user has access, the room will appear in a room listing. For guess-name rooms, this command will work transparently, adding the room to the user's known room list when it completes. For passworded rooms, access will be denied if the password is not supplied or is incorrect, or the command will complete successfully if the password is correct.
The third (and also) optional parameter is a “transient” flag. Normally, when a user enters a private and/or zapped room, the room is added to the user's known rooms list. If the transient flag is set to non-zero, this is called a “transient goto” which causes the user to enter the room without adding the room to the known rooms list.
The possible result codes are:
|OK||The command completed successfully. User is now in the room. (See the list of returned parameters below)|
|ERROR||The command did not complete successfully. Check the second and third positions of the result code to find out what happened:|
|NOT_LOGGED_IN||Of course you can't go there. You didn't log in.|
|PASSWORD_REQUIRED||Either a password was not supplied, or the supplied password was incorrect.|
|ROOM_NOT_FOUND||The requested room does not exist.|
The typical procedure for entering a passworded room would be:
- Execute a GOTO command without supplying any password.
- ERROR + PASSWORD_REQUIRED will be returned. The client now knows that the room is passworded, and prompts the user for a password.
- Execute a GOTO command, supplying both the room name and the password.
- If OK is returned, the command is complete. If, however, ERROR + PASSWORD_REQUIRED is still returned, tell the user that the supplied password was incorrect. The user remains in the room he/she was previously in.
When the command succeeds, these parameters are returned:
|0||The name of the room|
|1||Number of unread messages in this room|
|2||Total number of messages in this room|
|3||Info flag: set to nonzero if the user needs to read this room's info file (see RINF command below)|
|4||Various flags associated with this room. (See LKRN cmd above)|
|5||The highest message number present in this room|
|6||The highest message number the user has read in this room|
|7||Boolean flag: 1 if this is a Mail> room, 0 otherwise.|
|8||Aide flag: 1 if the user is either the Room Aide for this room, or is a regular Aide (this makes access checks easy).|
|9||The number of new Mail messages the user has (useful for alerting the user to the arrival of new mail during a session)|
|10||The floor number this room resides on|
|11||The current“view” for this room (see views.txt for more info)|
|12||The default“view” for this room|
|13||Boolean flag: 1 if this is the user's Trash folder, 0 otherwise.|
|14||More flags associated with this room|
|15||Timestamp of the last write activity in this room (addition or deletion of messages, reconfiguration of room, etc)|
The default view gives the client a hint as to what views the user should be allowed to select. For example, it would be confusing to allow messages in a room intended for calendar items. The server does not enforce these restrictions, though.
This is a lightweight command which may be used by a client to quickly determine whether there has been any activity in the current room (added or deleted messages, modification of the room's configuration, etc). It is called with no parameters, and returns OK followed by two parameters: the name of the room, and the modification timestamp.
This command obtains a listing of all the messages in the current room which the client may request. This command may be passed a single parameter: either “all”, “old”, or “new” to request all messages, only old messages, or new messages. Or it may be passed two parameters: “last” plus a number, in which case that many message pointers will be returned; “first” plus a number, for the corresponding effect; or “gt” plus a number, to list all messages in the current room with a message number greater than the one specified; or “lt” plus a number, to list all messages in the current room with a message number less than the one specified. If no parameters are specified, “all” is assumed.
In addition, the first parameter may be set to “search”, in which case the third parameter must be a search string. This will request all messages in the current room whose text contains the search string.
The third argument, may be either 0 or 1. If it is 1, this command behaves differently: before a listing is returned, the client must transmit a list of fields to search for. The field headers are listed below in the writeup for the "MSG0" command.
The optional fourth argument may also be either 0 or 9. If it is 9, the output of this command will include not only a list of message numbers, but a simple header summary of each message as well. This is somewhat resource intensive so you shouldn't do this unless you absolutely need all the headers immediately. The fields which are output (in the usual delimited fashion, of course) are: message number, timestamp, display name, node name, Internet email address (if present), subject (if present), hash of message-id (if present), comma-separated hashes of message thread references (if present).
This command can return three possible results. ERROR + NOT_LOGGED_IN will be returned if no user is currently logged in. Otherwise, LISTING_FOLLOWS will be returned, and the listing will consist of zero or more message numbers, one per line. The listing ends, as always, with the string “000” alone on a line by itself. The listed message numbers can be used to request messages from the system. If “search mode” is being used, the server will return START_CHAT_MODE, and the client is expected to transmit the search criteria, and then read the message list.
Since this is somewhat complex, here are some examples:
Example 1: Read all new messages
Client: MSGS NEW Server: 100 Message list... 523218 523293 523295 000
Example 2: Read the last five messages
Client: MSGS LAST|5 Server: 100 Message list... 523190 523211 523218 523293 523295 000
Example 3: Read all messages written by “IGnatius T Foobar”
Client: MSGS ALL|0|1 Server: 800 Send template then receive message list Client: from|IGnatius T Foobar 000 Server: 518604 519366 519801 520201 520268 520805 520852 521579 521720 522571 000
Note that in “search mode” the client may specify any number of search criteria. These criteria are applied with an AND logic.
Another note: anyone reading through the code may observe that there are other undocumented parameters which may be supplied to this command. These are deprecated and should not be used.
Beginning with version 5.80, Citadel supports the concept of setting or clearing the “seen” flag for each individual message, instead of only allowing a “last seen” pointer. In fact, the old semantics are implemented in terms of the new semantics. This command requires two arguments: the number of the message to be set, and a 1 or 0 to set or clear the “seen” bit.
This command returns OK, unless the user is not logged in or a usage error occurred, in which case it returns ERROR. Please note that no checking is done on the supplied data; if the requested message does not exist, the SEEN command simply returns OK without doing anything.
This command retrieves the list of “seen” (as opposed to unread) messages for the current room. It returns OK followed by an IMAP-format message list.
Set the preferred view for the current user in the current room. Please see views.txt for more information on views. The sole parameter for this command is the type of view requested. VIEW returns OK on success or ERROR on failure.
Please do not use this command. It is not intended to remain in the protocol in its current form. If you want to perform a full text search, use the MSGS command with the 'search' subcommand instead.
The current implementation accepts a search string as its sole argument, and will respond with LISTING_FOLLOWS followed by a list of messages (globally, not just in the current room) which contain ALL of the words in the search string. If the client desires an “exact phrase” match, it must then slow-search the text of each returned message for the exact string. The client should also compare the returned message numbers against those which actually exist in the room or rooms being searched. In particular, clients should avoid telling the user about messages which exist only in rooms to which the user does not have access.
Returns the message number, if present, of the message in the current room which is indexed using the supplied EUID (exclusive message ID). There can be only one message in a room with any given EUID; if another message arrives with the same EUID, the existing one is replaced. This makes it possible to reference things like calendar items using an immutable URL that does not change even when the message number changes due to an update.
The format of this command is: EUID <euid>
If successful, EUID returns OK followed by a message number. If no message exists in the current room with the supplied EUID, the command returns ERROR+MESSAGE_NOT_FOUND.
Delete one or more messages from the current room. The one argument that should be passed to this command is a message number, or a list of message numbers separated by commas, to be deleted.
The return value will be OK if one or more messages were deleted, or an ERROR code.
Please note that is operation only deletes the message pointer from the room. The actual “delete from disk” operation will take place during the next database purge, provided that the message is not also present in one or more additional rooms.
Move or copy a message to a different room. This command expects to be passed three arguments:
|0||the message number(s) of the message to be moved or copied.|
|1||the name of the target room.|
|2||flag: 0 to move the message, 1 to copy it without deleting from the source room.|
This command never creates or deletes copies of a message; it merely moves around links. When a message is moved, its reference count remains the same. When a message is copied, its reference count is incremented.
You can move/copy multiple messages with a single command by separating the message numbers with commas; for example:
This is the opposite of the MESG command - it allows the creation and editing of system messages. The only argument passed to EMSG is the name of the file being transmitted. If the file exists in any system message directory on the server it will be overwritten, otherwise a new file is created. EMSG returns SEND_LISTING on success or ERROR+HIGHER_ACCESS_REQUIRED if the user is not an Aide.
Typical client software would use MESG to retrieve any existing message into an edit buffer, then present an editor to the user and run EMSG if the changes are to be saved.
This command is used to enter messages into the system. It accepts four arguments:
|0||post||Post flag. This should be set to 1 to post a message. If it is set to 0, the server only returns OK or ERROR (plus any flags describing the error) without reading in a message. Client software should, in fact, perform this operation at the beginning of an “enter message” command before starting up its editor, so the user does not end up typing a message in vain that will not be permitted to be saved.|
|1||recp||Recipient (To: field). This argument is utilized only for private mail. It is ignored for public messages. It contains, of course, the name of the recipient(s) of the message.|
|2||anon_flag||Anonymous flag. This argument is ignored unless the room allows anonymous messages. In such rooms, this flag may be set to 1 to flag a message as anonymous, otherwise 0 for a normal message.|
|3||format_type||Format type. Any valid Citadel format type may be used (this will typically be 0; see the MSG0 command below).|
|4||subject||Subject. If present, this argument will be used as the subject of the message.|
|5||newusername||Post name. This is the 'display name' or 'screen name' to be used as the author of the message. It is permissible to leave this field blank to allow the server to select a suitable default. The supplied name must be one of the names returned by a GVSN command, unless the user is an Aide.|
|6||do_confirm||Do Confirmation. NOTE: this changes the protocol semantics! When you set this to nonzero, ENT0 will reply with a confirmation message after you submit the message text. The reply code for the ENT0 command will be START_CHAT_MODE instead of SEND_LISTING.|
|7||cc||Recipient (Cc: field). This argument is utilized only for private mail. It is ignored for public messages. It contains, of course, the name of the recipient(s) of the message.|
|8||bcc||Recipient (Bcc: field). This argument is utilized only for private mail. It is ignored for public messages. It contains, of course, the name of the recipient(s) of the message.|
|9||supplied_euid||Exclusive message ID. When a message is submitted with an Exclusive message ID, any existing messages with the same ID will automatically be deleted. This is only applicable for Wiki rooms; other types of rooms either ignore the supplied ID (such as message boards and mailboxes) or derive the ID from a UUID native to the objects stored in them (such as calendars and address books).|
|10||newusermail||Email address. This is the Internet email address to be used as the author of the message. It is permissible to leave this field blank to allow the server to select a suitable default. The supplied name must be one of the names returned by a GVEA command.|
|11||references||If this is a reply to another message, supply a delimiter-separated list of message ID's for the thread, starting with the message being replied to, and ending with the thread root. Note that the delimiter is ”!” (exclamation point) rather than the vertical bar, because we are already using the vertical bar delimiter here.|
|Possible result codes|
|OK||The request is valid. (Client did not set the “post” flag, so the server will not read in message text.) If the message is an e-mail with a recipient, the text that follows the OK code will contain the exact name to which mail is being sent. The client can display this to the user. The implication here is that the name that the server returns will contain the correct upper and lower case characters. In addition, if the recipient is having his/her mail forwarded, the forwarding address will be returned.
In newer Citadel versions its followed by a |[0|1] that indicates whether the client should force the user to set a message subject.
|SEND_LISTING||The request is valid. The client should now transmit the text of the message (ending with a 000 on a line by itself, as usual).|
|START_CHAT_MODE||The request is valid. The client should now transmit the text of the message, ending with a 000 on a line by itself. After transmitting the 000 terminator, the client MUST read in the confirmation from the server, which will also end with 000 on a line by itself. The format of the confirmation appears below.|
|ERROR + NOT_LOGGED_IN||Not logged in.|
|ERROR + HIGHER_ACCESS_REQUIRED||Higher access is required. An explanation follows, worded in a form that can be displayed to the user.|
|ERROR + NO_SUCH_USER||The specified recipient does not exist.|
The format of the confirmation message, if requested, is as follows:
|1||The new message number on the server for the message. It will be positive for a real message number, or negative to denote that an error occurred. If an error occurred, the message was not saved.|
|2||A human-readable confirmation or error message.|
|3||The resulting Exclusive UID of the message, if present. (More may be added to this in the future, so do not assume that there will only be these lines output. Keep reading until 000 is received.)|
Returns LISTING_FOLLOWS followed by a list of one or more “screen names” which the user may use to post messages (argument 5 to an ENT0 command). The user must be logged in or the command will return ERROR+NOT_LOGGED_IN.
Returns LISTING_FOLLOWS followed by a list of one or more Internet email addresses which the user may use to post messages (argument 10 to an ENT0 command). The user must be logged in or the command will return ERROR+NOT_LOGGED_IN.
Returns LISTING_FOLLOWS followed by a list of zero or more contacts (display name plus email address in RFC822 format) found in any vCards in the current room. This command is used to rapidly output the list of contacts in an address book room. The user must be logged in or the command will return ERROR+NOT_LOGGED_IN.
Due to the several needs of clients to get preformated messages, citadel offers several modes to clients to display a message (or parts of it)
This is a command used to read the text of a message. “Mode 0” implies that other MSG commands (MSG1, MSG2, etc.) will probably be added later on to read messages in more robust formats. This command should be passed two arguments. The first is the message number of the message being requested. The second argument specifies whether the client wants headers and/or message body:
|0||Headers and body|
|3||Headers only, with MIME information suppressed (this runs faster)|
If the request is denied, ERROR + NOT_LOGGED_IN or ERROR + MESSAGE_NOT_FOUND will be returned. Otherwise, LISTING_FOLLOWS will be returned, followed by the contents of the message. The following fields may be sent:
|type=||Formatting type. see the next table for the currently defined types|
|msgn=||The message ID of this message on the system it originated on.|
|path=||An e-mailable path back to the user who wrote the message.|
|time=||The date and time of the message, in Unix format (the number of seconds since midnight on January 1, 1970, GMT).|
|from=||The name of the author of the message.|
|rcpt=||If the message is a private e-mail, this is the recipient.|
|room=||The name of the room the message originated in.|
|node=||The short node name of the system this message originated on.|
|hnod=||The long node name of the system this message originated on.|
|zaps=||The id/node of a message which this one zaps (supersedes).|
|part=||Information about a MIME part embedded in this message.|
|pref=||formation about a multipart MIME prefix such as “multipart/mixed” or “multipart/alternative”. This will be output immediately prior to the various “part=” lines which make up the multipart section.|
|suff=||Information about a multipart MIME suffix. This will be output immediately following the various “part=” lines which make up the multipart section.|
|text||Note that there is no ”=” after the word “text”. This string signifies that the message text begins on the next line.|
|0||FMT_CITADEL||“traditional” Citadel formatting. This means that newlines should be treated as spaces UNLESS the first character on the next line is a space. In other words, only indented lines should generate a newline on the user's screen when the message is being displayed. This allows a message to be formatted to the reader's screen width. It also allows the use of proportional fonts.|
|1||FMT_FIXED||a simple fixed-format message. The message should be displayed to the user's screen as is, preferably in a fixed-width font that will fit 80 columns on a screen.|
|4||FMT_RFC822||MIME format message. The message text is expected to contain a header with the “Content-type:” directive (and possibly others).|
MSG2 follows the same calling convention as MSG0.
This command will output the raw RFC822 message source. If the message on disk is not in RFC822 format, it will be converted into RFC822 format. MSG2 may be used by clients which prefer to perform the full RFC822/MIME decode on the client side.
MSG3 is for use by internal programs only and should not be utilized by user-mode clients. It does require IPGM authentication. MSG3 follows the same calling convention as the other MSG commands, but upon success returns BINARY_FOLLOWS followed by a data block containing the _raw_ message format on disk.
This is the equivalent of MSG0, except it's a bit smarter about messages in rich text formats. Immediately following the “text” directive, the server will output RFC822-like MIME part headers such as “Content-type:” and “Content-length:”. MIME formats are chosen and/or converted based on the client's preferred format settings, which are set using the MSGP command, described below.
The MSG4 command also accepts an optional second argument, which may be the MIME part specifier of an encapsulated message/rfc822 message. This is useful for fetching the encapsulated message instead of the top-level message, for example, when someone has forwarded a message as an attachment. Note that the only way for the client to know the part specifier is to fetch the top-level message and then look for attachments of type message/rfc822, and then call MSG4 again with that part specifier.
these commands manipulate parts of messages, available in Multipart Mime Format as specified in RFC 822. TODO
Client tells the server what MIME content types it knows how to handle, and the order in which it prefers them. This is similar to an HTTP “Accept:” header.
The parameters to a MSGP command are the client's acceptable MIME content types, in the order it prefers them (from most preferred to least preferred). For example:
There is also a special form of this command, which may be used for the client to indicate to the server that it prefers to decode Base64 and quoted-printable on the client side. If this command is issued, these encodings will not be decoded prior to transmitting messages to the client. This is done with the following form:
The MSGP command always returns OK.
Opens, as a download file, a component of a MIME-encoded message. The two parameters which must be passed to this command are the message number and the name of the desired section. If the message or section does not exist, an appropriate ERROR code will be returned; otherwise, if the open is successful, this command will succeed returning the same information as an OPEN command.
The desired section may be specified using either its part number or its content-id.
Similar to OPNA, and with the same calling syntax. The difference is that instead of opening a download file for block transfer, this command outputs the entire decoded MIME section at once, using a BINARY_FOLLOWS response. This is useful for outputting small objects such as calendar items.
The desired section may be specified using either its part number or its content-id.
These commands are usable in Citadel Wiki rooms only.
Displays the edit history for the specified page. Returns LISTING_FOLLOWS and a delimited list of edits. The fields of each line are:
|0||The UUID of the edit|
|1||Timestamp of the edit|
|2||Name of the user who performed the edit|
|3||The node on which that user resides|
Performs an operation on a specific revision (whose UUID has been learned from a “history” command) of a specific page. The valid operations are “fetch” and “revert”. “fetch” will simply retrieve the specified revision of the page, while “revert” will actually make that revision the current one. In either case, this command will return OK followed by a message number.
In the case of a “fetch” operation, the client will probably want to then fetch the message with that number in order to display the desired revision of the page. The message has been saved in a hidden room in an invalid namespace, and will therefore be deleted from disk the next time the auto-purger runs.