* serv_notes.c: added skeleton module
authorArt Cancro <ajc@citadel.org>
Fri, 22 Oct 2004 02:53:25 +0000 (02:53 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 22 Oct 2004 02:53:25 +0000 (02:53 +0000)
* serv_newuser.c: corrected internal comment
* techdoc: renamed session.txt to protocol.txt because it really isn't
  a session layer protocol, it's more of an application layer protocol.

citadel/ChangeLog
citadel/Makefile.in
citadel/serv_extensions.c
citadel/serv_newuser.c
citadel/serv_notes.c [new file with mode: 0644]
citadel/techdoc/protocol.txt [new file with mode: 0644]
citadel/techdoc/session.txt [deleted file]

index c055cf7a3a72dc272b196872d2ff679fa37f2450..1deed170ebeef50fbfaf88ab18558d0ba8ccb7db 100644 (file)
@@ -1,4 +1,10 @@
  $Log$
+ Revision 626.13  2004/10/22 02:53:25  ajc
+ * serv_notes.c: added skeleton module
+ * serv_newuser.c: corrected internal comment
+ * techdoc: renamed session.txt to protocol.txt because it really isn't
+   a session layer protocol, it's more of an application layer protocol.
+
  Revision 626.12  2004/10/13 02:11:00  ajc
  * Repaired a completely broken <;Z>ap floor command.
 
@@ -6162,4 +6168,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
-
index 1465b41cc4cb874d602c0c3f0898242734223a5a..00a99d163182295db5850c2ecee461a309cb755d 100644 (file)
@@ -36,6 +36,7 @@ SERV_MODULES=serv_chat.o \
        serv_listsub.o \
        serv_netfilter.o \
        serv_newuser.o \
+       serv_notes.o \
        serv_pas2.o md5.o \
        serv_inetcfg.o \
        serv_rwho.o \
@@ -94,7 +95,7 @@ SOURCES=aidepost.c auth.c base64.c chkpwd.c citadel.c citadel_ipc.c \
        serv_spam.c serv_test.c serv_mrtg.c serv_spam.c serv_upgrade.c \
        serv_vandelay.c serv_vcard.c server_main.c setup.c snprintf.c \
        stress.c support.c sysdep.c tools.c user_ops.c userlist.c \
-       whobbs.c vcard.c
+       whobbs.c vcard.c serv_notes.c
 
 DEP_FILES=$(SOURCES:.c=.d)
 
index d69a85dea0506d8b34d0eee64579d7bd9c38b2d3..21d36c66804fff9367ef32c07cc464d294eb2a50 100644 (file)
@@ -104,6 +104,7 @@ void initialize_server_extensions(void)
 {
        serv_bio_init();
        serv_calendar_init();
+       serv_notes_init();
        serv_ldap_init();
        serv_chat_init();
        serv_expire_init();
index c46f150503573b5e174d6dd5810eb71388adaf5c..5cc13e9cbebecda9d181e5baa10482c7bc819728 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * $Id$
  *
- * A skeleton module to test the dynamic loader.
+ * Automaticalyl copies the contents of a "New User Greetings" room to the
+ * inbox of any new user upon account creation.
  *
  */
 
diff --git a/citadel/serv_notes.c b/citadel/serv_notes.c
new file mode 100644 (file)
index 0000000..c5d537d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Handles functions related to yellow sticky notes.
+ *
+ */
+
+#include "sysdep.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pwd.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#include <sys/wait.h>
+#include <string.h>
+#include <limits.h>
+#include "citadel.h"
+#include "server.h"
+#include "sysdep_decls.h"
+#include "citserver.h"
+#include "support.h"
+#include "config.h"
+#include "serv_extensions.h"
+#include "room_ops.h"
+#include "user_ops.h"
+#include "policy.h"
+#include "database.h"
+#include "msgbase.h"
+
+
+char *serv_notes_init(void)
+{
+   return "$Id$";
+}
diff --git a/citadel/techdoc/protocol.txt b/citadel/techdoc/protocol.txt
new file mode 100644 (file)
index 0000000..993b9bb
--- /dev/null
@@ -0,0 +1,2143 @@
+              APPLICATION LAYER PROTOCOL FOR THE CITADEL SYSTEM
+         (c) 1995-2004 by Art Cancro et. al.    All Rights Reserved
+
+
+ INTRODUCTION
+ ------------
+
+ This is an attempt to document the session layer protocol used by the
+Citadel system, beginning with version 4.00, which is the first version
+to implement a client/server paradigm.  It is intended as a resource for
+programmers who intend to develop their own Citadel clients, but it may have
+other uses as well.
+
+
+ IMPORTANT NOTE TO DEVELOPERS!
+ -----------------------------
+
+ Anyone who wants to add commands or other functionality to this protocol,
+*please* get in touch so that these efforts can be coordinated.  New
+commands added by other developers can be added to this document, so we
+don't end up with new server commands from multiple developers which have
+the same name but perform different functions.  If you don't coordinate new
+developments ahead of time, please at least send in an e-mail documenting
+what you did, so that your new commands can be added to this document.
+
+ The coordinator of the Citadel project is Art Cancro
+<ajc@uncensored.citadel.org>.
+
+
+ CONNECTING TO A SERVER
+ ----------------------
+
+ The protocols used below the session layer are beyond the scope of this
+document, but we will briefly cover the methodology employed by Citadel.
+
+ Citadel offers Citadel BBS service using TCP/IP.  It does so via a
+multithreaded server listening on a TCP port.  Local connections may also
+be made using the same protocol using Unix domain sockets.
+
+ The port number officially assigned to Citadel by the IANA is 504/tcp.  Since
+our session layer assumes a clean, reliable, sequenced connection, the use
+of UDP would render the server unstable and unusable, so we stick with TCP.
+
+
+ GENERAL INFORMATION ABOUT THE SERVER
+ ------------------------------------
+
+ The server is connection-oriented and stateful: each client requires its own
+connection to a server process, and when a command is sent, the client must
+read the response, and then transfer data or change modes if necessary.
+
+ The session layer is very much like other Internet protocols such as SMTP
+or NNTP.  A client program sends one-line commands to the server, and the
+server responds with a three-digit numeric result code followed by a message
+describing what happened.  This cycle continues until the end of the
+session.
+
+ Unlike protocols such as FTP, all data transfers occur in-band.  This means
+that the same connection that is used for exchange of client/server
+messages, will also be used to transfer data back and forth.  (FTP opens a
+separate connection for data transfers.)  This keeps protocol administration
+straightforward, as it can traverse firewalls without any special protocol
+support on the firewall except for opening the port number.
+
+
+ RESULT CODES
+ ------------
+
+ The server will respond to all commands with a 3-digit result code, which
+will be the first three characters on the line.  The rest of the line may
+contain a human-readable string explaining what happened.  (Some client
+software will display some of these strings to the user.)
+
+ The first digit is the most important.  The following codes are defined for
+this position: ERROR, OK, MORE_DATA, LISTING_FOLLOWS, and SEND_LISTING.
+
+ The second and third digits may provide a reason as to why a command
+succeeded or failed.  See ipcdef.h for the available codes.
+
+ ERROR means the command did not complete.
+ OK means the command executed successfully.
+ MORE_DATA means the command executed partially.  Usually this means that
+another command needs to be executed to complete the operation.  For example,
+sending the USER command to log in a user usually results in a MORE_DATA
+result code, because the client needs to execute a PASS command to send the
+password and complete the login.
+ LISTING_FOLLOWS means that after the server response, the server will
+output a listing of some sort.  The client *must* read the listing, whether
+it wants to or not.  The end of the listing is signified by the string
+"000" on a line by itself.
+ SEND_LISTING is the opposite of LISTING_FOLLOWS.  It means that the client
+should begin sending a listing of some sort.  The client *must* send something,
+even if it is an empty listing.  Again, the listing ends with "000" on a line
+by itself.
+ BINARY_FOLLOWS and SEND_BINARY mean that the client must immediately send
+or receive a block of binary data.  The first parameter will always be the
+number of bytes.
+ ASYNC_MESSAGE_FOLLOWS means that an asynchronous, or unsolicited, message
+follows.  The next line will be one of the above codes, and if a data transfer
+is involved it must be handled immediately.  Note that the client will not
+receive this type of response unless it indicates to the server that it is
+capable of handling them; see the writeup of the ASYN command later in this
+document.
+
+ PARAMETERIZATION
+ ----------------
+
+ Zero or more parameters may be passed to a command.  When more than one
+parameter is passed to a command, they should be separated by the "|"
+symbol like this:
+  SETU 80|24|260
+ In this example, we're using the "SETU" command and passing three
+parameters: 80, 24, and 260.
+
+ When the server spits out data that has parameters, if more than one
+parameter is returned, they will be separated by the "|" symbol like
+this:
+  200 80|24|260
+ In this example, we just executed the "GETU" command, and it returned us
+an OK result code (the '2' in the 200) and three parameters: 80, 24, and
+260.
+
+
+ COMMANDS
+ --------
+
+ This is a listing of all the commands that a Citadel server can execute.
+
+
+ NOOP   (NO OPeration)
+
+ This command does nothing.  It takes no arguments and always returns
+OK.  It is intended primarily for testing and development, but it might also
+be used as a "keep alive" command to prevent the server from timing out, if
+it's running over a transport that needs this type of thing.
+
+
+ ECHO   (ECHO something)
+
+ This command also does nothing.  It simply returns OK followed by whatever
+its arguments are.
+
+
+ QUIT   (QUIT)
+
+ Terminate the server connection.  This command takes no arguments.  It
+returns OK and closes the connection immediately.
+
+
+ LOUT   (LogOUT)
+
+ Log out the user without closing the server connection.  It always returns
+OK even if no user is logged in.
+
+
+ USER   (send USER name)
+
+ The first step in logging in a user.  This command takes one argument: the
+name of the user to be logged in.  If the user exists, a MORE_DATA return
+code will be sent, which means the client should execute PASS as the next
+command.  If the user does not exist, ERROR + NO_SUCH_USER is returned.
+
+
+ PASS   (send PASSword)
+
+ The second step in logging in a user.  This command takes one argument: the
+password for the user we are attempting to log in.  If the password doesn't
+match the correct password for the user we specified for the USER command,
+ERROR + PASSWORD_REQUIRED is returned.  If a USER command has not been
+executed yet, ERROR + USERNAME_REQUIRED is returned.  If a user is already
+logged in, ERROR + ALREADY_LOGGED_IN is returned.  If the password is
+correct, OK is returned and the user is now logged in... and most of the
+other server commands can now be executed.  Along with OK, the following
+parameters are returned:
+
+ 0 - The user's name (in case the client wants the right upper/lower casing)
+ 1 - The user's current access level
+ 2 - Times called
+ 3 - Messages posted
+ 4 - Various flags (see citadel.h)
+ 5 - User number
+ 6 - Time of last call (UNIX timestamp)
+
+
+ NEWU   (create NEW User account)
+
+ This command creates a new user account AND LOGS IT IN.  The argument to
+this command will be the name of the account.  No case conversion is done
+on the name.  Note that the new account is installed with a default
+configuration, and no password, so the client should immediately prompt the
+user for a password and install it with the SETP command as soon as this
+command completes.  This command returns OK if the account was created and
+logged in, ERROR + ALREADY_EXISTS if another user already exists with this
+name, ERROR + NOT_HERE if self-service account creation is disabled,
+ERROR + MAX_SESSIONS_EXCEEDED if too many users are logged in, ERROR +
+USERNAME_REQUIRED if a username was not provided, or ERROR + ILELGAL_VALUE
+if the username provided is invalid.  If OK, it will also return the same
+parameters that PASS returns.
+
+ Please note that the NEWU command should only be used for self-service
+user account creation.  For administratively creating user accounts, please
+use the CREU command.
+
+
+ SETP   (SET new Password)
+
+ This command sets a new password for the currently logged in user.  The
+argument to this command will be the new password.  The command always
+returns OK, unless the client is not logged in, in which case it will return
+ERROR + NOT_LOGGED_IN, or if the user is an auto-login user, in which case
+it will return ERROR + NOT_HERE.
+
+
+ CREU   (CREate new User account)
+
+ This command creates a new user account AND DOES NOT LOG IT IN.  The first
+argument to this command will be the name of the account.  No case conversion
+is done on the name.  Note that the new account is installed with a default
+configuration, and no password.  The second argument is optional, and will be
+an initial password for the user.  This command returns OK if the account was
+created, ERROR + HIGHER_ACCESS_REQUIRED if the user is not an Aide, ERROR +
+USERNAME_REQUIRED if no username was specified, or ERROR + ALREADY_EXISTS if
+another user already exists with this name.
+
+ Please note that CREU is intended to be used for activities in which a
+system administrator is creating user accounts.  For self-service user
+account creation, use the NEWU command.
+
+
+ LKRN   (List Known Rooms with New messages)
+
+ List known rooms with new messages.  If the client is not logged in, ERROR +
+NOT_LOGGED_IN is returned.  Otherwise, LISTING_FOLLOWS is returned, followed
+by the room listing.  Each line in the listing contains the full name of a
+room, followed by the '|' symbol, and then a number that may contain the
+following bits:
+
+#define QR_PERMANENT   1               /* Room does not purge              */
+#define QR_PRIVATE     4               /* Set for any type of private room */
+#define QR_PASSWORDED  8               /* Set if there's a password too    */
+#define QR_GUESSNAME   16              /* Set if it's a guessname room     */
+#define QR_DIRECTORY   32              /* Directory room                   */
+#define QR_UPLOAD      64              /* Allowed to upload                */
+#define QR_DOWNLOAD    128             /* Allowed to download              */
+#define QR_VISDIR      256             /* Visible directory                */
+#define QR_ANONONLY    512             /* Anonymous-Only room              */
+#define QR_ANON2       1024            /* Anonymous-Option room            */
+#define QR_NETWORK     2048            /* Shared network room              */
+#define QR_PREFONLY    4096            /* Preferred status needed to enter */
+#define QR_READONLY    8192            /* Aide status required to post     */
+
+ Then it returns another '|' symbol, followed by a second set of bits comprised
+of the following:
+
+#define QR2_SYSTEM     1               /* System room; hide by default     */
+#define QR2_SELFLIST   2               /* Self-service mailing list mgmt   */
+
+ Other bits may be defined in the future.  The listing terminates, as with
+all listings, with "000" on a line by itself.
+
+ Starting with version 4.01 and above, floors are supported.  The first
+argument to LKRN should be the number of the floor to list rooms from.  Only
+rooms from this floor will be listed.  If no arguments are passed to LKRN, or
+if the floor number requested is (-1), rooms on all floors will be listed.
+
+ The third field displayed on each line is the number of the floor the room
+is on.  The LFLR command should be used to associate floor numbers with
+floor names.
+
+ The fourth field displayed on each line is a "room listing order."  Unless
+there is a compelling reason not to, clients should sort any received room
+listings by this value.
+ The fifth field is a special bit bucket containing fields which pertain to
+room access controls:
+
+#define UA_KNOWN                2      /* Known room */
+#define UA_GOTOALLOWED          4      /* Access will be granted to this room
+                                        * if the user calls it up by name */
+#define UA_HASNEWMSGS           8      /* Unread messages exist in room */
+#define UA_ZAPPED              16      /* Zapped from known rooms list */
+ LKRO   (List Known Rooms with Old [no new] messages)
+
+ This follows the same usage and format as LKRN.
+
+
+ LZRM   (List Zapped RooMs)
+
+ This follows the same usage and format as LKRN and LKRO.
+
+
+ LKRA   (List All Known Rooms)
+
+ Same format.  Lists all known rooms, with or without new messages.
+
+
+ LRMS   (List all accessible RooMS)
+
+ Again, same format.  This command lists all accessible rooms, known and
+forgotten, with and without new messages.  It does not, however, list
+inaccessible private rooms.
+
+
+ LPRM   (List all Public RooMs)
+
+ Again, same format.  This command lists all public rooms, and nothing else.
+Unlike the other list rooms commands, this one can be executed without logging
+in.
+
+
+ GETU   (GET User configuration)
+
+ This command retrieves the screen dimensions and user options for the
+currently logged in account.  ERROR + NOT_LOGGED_IN will be returned if no
+user is logged in, of course.  Otherwise, OK will be returned, followed by
+four parameters.  The first parameter is the user's screen width, the second
+parameter is the user's screen height, and the third parameter is a bag of
+bits with the following meanings:
+
+ #define US_LASTOLD    16              /* Print last old message with new  */
+ #define US_EXPERT     32              /* Experienced user                 */
+ #define US_UNLISTED   64              /* Unlisted userlog entry           */
+ #define US_NOPROMPT   128             /* Don't prompt after each message  */
+ #define US_DISAPPEAR  512             /* Use "disappearing msg prompts"   */
+ #define US_PAGINATOR  2048            /* Pause after each screen of text  */
+
+ There are other bits, too, but they can't be changed by the user (see below).
+
+
+ SETU   (SET User configuration)
+
+ This command does the opposite of SETU: it takes the screen dimensions and
+user options (which were probably obtained with a GETU command, and perhaps
+modified by the user) and writes them to the user account.  This command
+should be passed three parameters: the screen width, the screen height, and
+the option bits (see above).  It returns ERROR + NOT_LOGGED_IN if no user is
+logged in, and ERROR + ILLEGAL_VALUE if the parameters are incorrect.
+
+ Note that there exist bits here which are not listed in this document.  Some
+are flags that can only be set by Aides or the system administrator.  SETU
+will ignore attempts to toggle these bits.  There also may be more user
+settable bits added at a later date.  To maintain later downward compatibility,
+the following procedure is suggested:
+
+ 1. Execute GETU to read the current flags
+ 2. Toggle the bits that we know we can toggle
+ 3. Execute SETU to write the flags
+
+ If we are passed a bit whose meaning we don't know, it's best to leave it
+alone, and pass it right back to the server.  That way we can use an old
+client on a server that uses an unknown bit without accidentally clearing
+it every time we set the user's configuration.
+
+
+ GOTO   (GOTO a 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 two additional reserved room names:
+ "_MAIL_" translates to the system's designated room for e-mail messages.
+ "_BITBUCKET_" goes to whatever room has been chosen for messages
+without a home.
+
+ 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:
+
+ 1. Execute a GOTO command without supplying any password.
+ 2. ERROR + PASSWORD_REQUIRED will be returned.  The client now knows that
+the room is passworded, and prompts the user for a password.
+ 3. Execute a GOTO command, supplying both the room name and the password.
+ 4. 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
+ 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.
+
+
+ MSGS   (get pointers to MeSsaGeS in this room)
+
+ 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, or "first" plus a
+number, for the corresponding effect.  If no parameters are specified, "all"
+is assumed.
+
+ In Citadel 5.00 and above, the client may also specify "gt" plus a number,
+to list all messages in the current room with a message number greater than
+the one specified.
+
+ The third argument, valid only in Citadel 5.60 and above, 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.
+
+ 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.
+
+
+ MSG0   (read MeSsaGe, mode 0)
+
+ 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
+ 1 = Headers only
+ 2 = Body only
+ 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.  The currently defined types are:
+  0 = "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 = 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 = MIME format message.  The message text is expected to contain a header
+with the "Content-type:" directive (and possibly others).
+
+ 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=   Information 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.
+
+
+ WHOK   (WHO Knows room)
+
+ This command is available only to Aides.  ERROR + HIGHER_ACCESS_REQUIRED 
+will be returned if the user is not an Aide.  Otherwise, it returns
+LISTING_FOLLOWS and then lists, one user per line, every user who has
+access to the current room.
+
+
+ INFO   (get server INFO)
+
+ This command will *always* return LISTING_FOLLOWS and then print out a
+listing of zero or more strings.  Client software should be written to expect
+anywhere from a null listing to an infinite number of lines, to allow later
+backward compatibility.  The current implementation defines the following
+parts of the listing:
+
+ Line 1  - Your unique session ID on the server
+ Line 2  - The node name of the server BBS
+ Line 3  - Human-readable node name of the server BBS
+ Line 4  - The fully-qualified domain name (FQDN) of the server
+ Line 5  - The name of the server software, i.e. "Citadel 4.00"
+ Line 6  - (The revision level of the server code) * 100
+ Line 7  - The geographical location of the BBS (city and state if in the US)
+ Line 8  - The name of the system administrator
+ Line 9  - A number identifying the server type (see below)
+ Line 10 - The text of the system's paginator prompt
+ Line 11 - Floor Flag.  1 if the system supports floors, 0 otherwise.
+ Line 12 - Paging level.  0 if the system only supports inline paging,
+           1 if the system supports "extended" paging (check-only and
+           multiline modes).  See the SEXP command for further information.
+ Line 13 - The "nonce" for this session, for support of APOP-style
+           authentication.  If this field is present, clients may authenticate
+           in this manner.
+ Line 14 - Set to nonzero if this server supports the QNOP command.
+ Line 15 - Set to nonzero if this server is capable of connecting to a
+           directory service using LDAP.
+
+ *** NOTE! ***   The "server type" code is intended to promote global
+compatibility in a scenario in which developers have added proprietary
+features to their servers or clients.  We are attempting to avoid a future
+situation in which users need to keep different client software around for
+each BBS they use.  *Please*, if you are a developer and plan to add
+proprietary features:
+
+ -> Your client programs should still be able to utilize servers other than
+your own.
+ -> Clients other than your own should still be able to utilize your server,
+even if your proprietary extensions aren't supported.
+ -> Please contact Art Cancro <ajc@uncensored.citadel.org> and obtain a unique
+server type code, which can be assigned to your server program.
+ -> If you document what you did in detail, perhaps it can be added to a
+future release of the Citadel program, so everyone can enjoy it.  Better
+yet, just work with the Citadel development team on the main source tree.
+
+ If everyone follows this scheme, we can avoid a chaotic situation with lots
+of confusion about which client program works with which server, etc.  Client
+software can simply check the server type (and perhaps the revision level)
+to determine ahead of time what commands may be utilized.
+
+ Please refer to "developers.txt" for information on what codes belong to whom.
+
+
+
+ RDIR   (Read room DIRectory)
+
+ Use this command to read the directory of a directory room.  ERROR + NOT_HERE
+will be returned if the room has no directory, ERROR + HIGHER_ACCESS_REQUIRED
+will be returned if the room's directory is not visible and the user does not
+have Aide or Room Aide privileges, ERROR + NOT_LOGGED_IN will be returned if
+the user is not logged in; otherwise LISTING_FOLLOWS will be returned,
+followed by the room's directory.  Each line of the directory listing will
+contain three fields: a filename, the length of the file, and a description.
+
+ The server message contained on the same line with LISTING_FOLLOWS will
+contain the name of the system and the name of the directory, such as:
+
+  uncensored.citadel.org|/usr/bbs/files/my_room_directory
+
+
+ SLRP   (Set Last-message-Read Pointer)
+
+ This command marks all messages in the current room as read (seen) up to and
+including the specified number.  Its sole parameter is the number of the last
+message that has been read.  This allows the pointer to be set at any
+arbitrary point in the room.  Optionally, the parameter "highest" may be used
+instead of a message number, to set the pointer to the number of the highest
+message in the room, effectively marking all messages in the room as having
+been read (ala the Citadel <G>oto command).
+
+ The command will return OK if the pointer was set, or ERROR + NOT_LOGGED_IN
+if the user is not logged in.  If OK is returned, it will be followed by a
+single argument containing the message number the last-read-pointer was set to.
+
+
+ INVT   (INViTe a user to a room)
+
+ This command may only be executed by Aides, or by the room aide for the
+current room.  It is used primarily to add users to invitation-only rooms,
+but it may also be used in other types of private rooms as well.  Its sole
+parameter is the name of the user to invite.
+
+ The command will return OK if the operation succeeded.  ERROR + NO_SUCH_USER
+will be returned if the user does not exist, ERROR + HIGHER_ACCESS_REQUIRED
+will be returned if the operation would have been possible if the user had
+higher access, and ERROR + NOT_HERE may be returned if the room is not a
+private room.
+
+
+ KICK   (KICK a user out of a room)
+
+ This is the opposite of INVT: it is used to kick a user out of a private
+room.  It can also be used to kick a user out of a public room, but the
+effect will only be the same as if the user <Z>apped the room - a non-stupid
+user can simply un-zap the room to get back in.
+
+
+ GETR   (GET Room attributes)
+
+ This command is used for editing the various attributes associated with a
+room.  A typical "edit room" command would work like this:
+ 1. Use the GETR command to get the current attributes
+ 2. Change some of them around
+ 3. Use SETR (see below) to save the changes
+ 4. Possibly also change the room aide using the GETA and SETA commands
+
+ GETR takes no arguments.  It will only return OK if the SETR command will
+also return OK.  This allows client software to tell the user that he/she
+can't edit the room *before* going through the trouble of actually doing the
+editing.  Possible return codes are:
+
+ ERROR+NOT_LOGGED_IN          - No user is logged in.
+ ERROR+HIGHER_ACCESS_REQUIRED - Not enough access.  Typically, only aides
+and the room aide associated with the current room, can access this command.
+ OK                           - Command succeeded.  Parameters are returned.
+
+ If OK is returned, the following parameters will be returned as well:
+
+ 0. The name of the room
+ 1. The room's password (if it's a passworded room)
+ 2. The name of the room's directory (if it's a directory room)
+ 3. Various flags (bits) associated with the room (see LKRN cmd above)
+ 4. The floor number on which the room resides
+ 5. The room listing order
+ 6. The default view for the room (see views.txt)
+ 7. A second set of flags (bits) associated with the room
+
+
+ SETR   (SET Room attributes)
+
+ This command sets various attributes associated with the current room.  It
+should be passed the following arguments:
+
+ 0. The name of the room
+ 1. The room's password (if it's a passworded room)
+ 2. The name of the room's directory (if it's a directory room)
+ 3. Various flags (bits) associated with the room (see LKRN cmd above)
+ 4. "Bump" flag (see below)
+ 5. The floor number on which the room should reside
+ 6. The room listing order
+ 7. The default view for the room (see views.txt)
+ 8. A second set of flags (bits) associated with the room
+
+ *Important: You should always use GETR to retrieve the current attributes of
+the room, then change what you want to change, and then use SETR to write it
+all back.  This is particularly important with respect to the flags: if a
+particular bit is set, and you don't know what it means, LEAVE IT ALONE and
+only toggle the bits you want to toggle.  This will allow for upward
+compatibility.
+
+ The _BASEROOM_, user's Mail> and Aide> rooms can only be partially edited.
+Any changes which cannot be made will be silently ignored.
+
+ If the room is a private room, you have the option of causing all users who
+currently have access, to forget the room.  If you want to do this, set the
+"bump" flag to 1, otherwise set it to 0.
+
+
+ GETA
+
+ This command is used to get the name of the Room Aide for the current room.
+It will return ERROR + NOT_LOGGED_IN if no user is logged in, or OK if the
+command succeeded.  Along with OK there will be returned one parameter: the
+name of the Room Aide.  A conforming server must guarantee that the user is
+always in some room.
+
+
+ SETA
+
+ The opposite of GETA, used to set the Room Aide for the current room.  One
+parameter should be passed, which is the name of the user who is to be the
+new Room Aide.  Under Citadel, this command may only be executed by Aides
+and by the *current* Room Aide for the room.  Return codes possible are:
+ ERROR + NOT_LOGGED_IN          (Not logged in.)
+ ERROR + HIGHER_ACCESS_REQUIRED (Higher access required.)
+ ERROR + NOT_HERE               (Room cannot be edited.)
+ OK                             (Command succeeded.)
+
+
+ ENT0   (ENTer message, mode 0)
+
+ This command is used to enter messages into the system.  It accepts four
+arguments:
+
+  0  -  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.  If it is set to 2, the
+server will accept an "apparent" post name if the user is privileged enough.
+This post name is arg 5.
+  1  -  Recipient.  This argument is utilized only for private mail messages.
+It is ignored for public messages.  It contains, of course, the name of the
+recipient of the message.
+  2  -  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.  Any valid Citadel format type may be used (this will
+typically be 0; see the MSG0 command above).
+  4  -  Subject.  If present, this argument will be used as the subject of
+the message.
+  5  -  Post name.  When postflag is 2, this is the name you are posting as.
+This is an Aide only command.
+
+ 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.
+  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).
+  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.
+
+
+ RINF   (read Room INFormation file)
+
+ Each room has associated with it a text file containing a description of
+the room, perhaps containing its intended purpose or other important
+information.  The info file for the Lobby> (the system's base room) is
+often used as a repository for system bulletins and the like.
+
+ This command, which accepts no arguments, is simply used to read the info
+file for the current room.  It will return LISTING_FOLLOWS followed by
+the text of the message (always in format type 0) if the request can be
+honored, or ERROR if no info file exists for the current room (which is
+often the case).  Other error description codes may accompany this result.
+
+ When should this command be used?  This is, of course, up to the discretion
+of client software authors, but in Citadel it is executed in two situations:
+the first time the user ever enters a room; and whenever the contents of the
+file change.  The latter can be determined from the result of a GOTO command,
+which will tell the client whether the file needs to be read (see GOTO above).
+
+
+ DELE   (DELEte a message)
+
+ Delete a message from the current room.  The one argument that should be
+passed to this command is the message number of the message to be deleted.
+The return value will be OK if the message was deleted, or an ERROR code.
+If the delete is successful, the message's reference count is decremented, and
+if the reference count reaches zero, the message is removed from the message
+base.
+
+
+ MOVE   (MOVE or copy a message to a different room)
+
+ Move or copy a message to a different room.  This command expects to be
+passed three arguments:
+ 0: the message number 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.
+
+
+ KILL   (KILL current room)
+
+ This command deletes the current room.  It accepts a single argument, which
+should be nonzero to actually delete the room, or zero to merely check
+whether the room can be deleted.
+
+ Once the room is deleted, the current room is undefined.  It is suggested
+that client software immediately GOTO another room (usually _BASEROOM_)
+after this command completes.
+
+ Possible return codes:
+
+ OK  -  room has been deleted (or, if checking only, request is valid).
+ ERROR+NOT_LOGGED_IN  -  no user is logged in.
+ ERROR+HIGHER_ACCESS_REQUIRED  -  not enough access to delete rooms.
+ ERROR+NOT_HERE  -  this room can not be deleted.
+
+
+ CRE8   (CRE[ate] a new room)
+
+ This command is used to create a new room.  Like some of the other
+commands, it provides a mechanism to first check to see if a room can be
+created before actually executing the command.  CRE8 accepts the following
+arguments:
+
+ 0  -  Create flag.  Set this to 1 to actually create the room.  If it is
+set to 0, the server merely checks that there is a free slot in which to
+create a new room, and that the user has enough access to create a room.  It
+returns OK if the client should go ahead and prompt the user for more info,
+or ERROR or ERROR+HIGHER_ACCESS_REQUIRED if the command will not succeed.
+ 1  -  Name for new room.
+ 2  -  Access type for new room:
+       0  -  Public
+       1  -  Private; can be entered by guessing the room's name
+       2  -  Private; can be entered by knowing the name *and* password
+       3  -  Private; invitation only (sometimes called "exclusive")
+       4  -  Personal (mailbox for this user only)
+ 3  -  Password for new room (if it is a type 2 room)
+ 4  -  Floor number on which the room should reside (optional)
+ 5  -  Set to 1 to avoid automatically gaining access to the created room.
+ 6  -  The default "view" for the room.
+
+ If the create flag is set to 1, the room is created (unless something
+went wrong and an ERROR return is sent), and the server returns OK, but
+the session is **not** automatically sent to that room.  The client still
+must perform a GOTO command to go to the new room.
+
+
+ FORG   (FORGet the current room)
+
+ This command is used to forget (zap) the current room.  For those not
+familiar with Citadel, this terminology refers to removing the room from
+a user's own known rooms list, *not* removing the room itself.  After a
+room is forgotten, it no longer shows up in the user's known room list,
+but it will exist in the user's forgotten room list, and will return to the
+known room list if the user goes to the room (in Citadel, this is
+accomplished by explicitly typing the room's name in a <.G>oto command).
+
+ The command takes no arguments.  If the command cannot execute for any
+reason, ERROR will be returned.  ERROR+NOT_LOGGED_IN or ERROR+NOT_HERE may
+be returned as they apply.
+
+ If the command succeeds, OK will be returned.  At this point, the current
+room is **undefined**, and the client software is responsible for taking
+the user to another room before executing any other room commands (usually
+this will be _BASEROOM_ since it is always there).
+
+
+ MESG    (read system MESsaGe)
+
+ This command is used to display system messages and/or help files.  The
+single argument it accepts is the name of the file to display.  IT IS CASE
+SENSITIVE.  Citadel looks for these files first in the "messages"
+subdirectory and then in the "help" subdirectory.
+
+ If the file is found, LISTING_FOLLOWS is returned, followed by a pathname
+to the file being displayed.  Then the message is printed, in format type 0
+(see MSG0 command for more information on this).  If the file is not found,
+ERROR is returned.
+
+ There are some "well known" names of system messages which client software
+may expect most servers to carry:
+
+ hello        -  Welcome message, to be displayed before the user logs in.
+ changepw     -  To be displayed whenever the user is prompted for a new
+                 password.  Warns about picking guessable passwords and such.
+ register     -  Should be displayed prior to the user entering registration.
+                 Warnings about not getting access if not registered, etc.
+ help         -  Main system help file.
+ goodbye      -  System logoff banner; display when user logs off.
+ roomaccess   -  Information about how public rooms and different types of
+                 private rooms function with regards to access.
+ unlisted     -  Tells users not to choose to be unlisted unless they're
+                 really paranoid, and warns that aides can still see
+                 unlisted userlog entries.
+
+ Citadel provides these for the Citadel Unix text client.  They are
+probably not very useful for other clients:
+
+ mainmenu     -  Main menu (when in idiot mode).
+ aideopt      -  .A?
+ readopt      -  .R?
+ entopt       -  .E?
+ dotopt       -  .?
+ saveopt      -  Options to save a message, abort, etc.
+ entermsg     -  Displayed just before a message is entered, when in
+                 idiot mode.
+
+
+ GNUR   (Get Next Unvalidated User)
+
+ This command shows the name of a user that needs to be validated.  If there
+are no unvalidated users, OK is returned.  Otherwise, MORE_DATA is returned
+along with the name of the first unvalidated user the server finds.  All of
+the usual ERROR codes may be returned as well (for example, if the user is
+not an Aide and cannot validate users).
+
+ A typical "Validate New Users" command would keep executing this command,
+and then validating each user it returns, until it returns OK when all new
+users have been validated.
+
+
+ GREG   (Get REGistration for user)
+
+ This command retrieves the registration info for a user, whose name is the
+command's sole argument.  All the usual error messages can be returned.  If
+the command succeeds, LISTING_FOLLOWS is returned, followed by the user's name
+(retrieved from the userlog, with the right upper and lower case etc.)  The
+contents of the listing contains one field per line, followed by the usual
+000 on the last line.
+
+ The following lines are defined.  Others WILL be added in the futre, so all
+software should be written to read the lines it knows about and then ignore
+all remaining lines:
+
+ Line 1:  User number
+ Line 2:  Password
+ Line 3:  Real name
+ Line 4:  Street address or PO Box
+ Line 5:  City/town/village/etc.
+ Line 6:  State/province/etc.
+ Line 7:  ZIP Code
+ Line 8:  Telephone number
+ Line 9:  Access level
+ Line 10: Internet e-mail address
+ Line 11: Country
+
+ Users without Aide privileges may retrieve their own registration using
+this command.  This can be accomplished either by passing the user's own
+name as the argument, or the string "_SELF_".  The command will always
+succeed when used in this manner, unless no user is logged in.
+
+
+ VALI   (VALIdate user)
+
+ This command is used to validate users.  Obviously, it can only be executed
+by users with Aide level access.  It should be passed two parameters: the
+name of the user to validate, and the desired access level
+
+ If the command succeeds, OK is returned.  The user's access level is changed
+and the "need validation" bit is cleared.  If the command fails for any
+reason, ERROR, ERROR+NO_SUCH_USER, or ERROR+HIGHER_ACCESS_REQUIRED will be
+returned.
+
+
+ EINF   (Enter INFo file for room)
+
+ Transmit the info file for the current room with this command.  EINF uses
+a boolean flag (1 or 0 as the first and only argument to the command) to
+determine whether the client actually wishes to transmit a new info file, or
+is merely checking to see if it has permission to do so.
+
+ If the command cannot succeed, it returns ERROR.
+ If the client is only checking for permission, and permission will be
+granted, OK is returned.
+ If the client wishes to transmit the new info file, SEND_LISTING is
+returned, and the client should transmit the text of the info file, ended
+by the usual 000 on a line by itself.
+
+
+ LIST   (user LISTing)
+
+ This is a simple user listing.  It always succeeds, returning
+LISTING_FOLLOWS followed by zero or more user records, 000 terminated.  The
+fields on each line are as follows:
+
+ 1. User name
+ 2. Access level
+ 3. User number
+ 4. Date/time of last login (Unix format)
+ 5. Times called
+ 6. Messages posted
+ 7. Password (listed only if the user requesting the list is an Aide)
+
+ Unlisted entries will also be listed to Aides logged into the server, but
+not to ordinary users.
+
+
+ REGI   (send REGIstration)
+
+ Clients will use this command to transmit a user's registration info.  If
+no user is logged in, ERROR+NOT_LOGGED_IN is returned.  Otherwise,
+SEND_LISTING is returned, and the server will expect the following information
+(terminated by 000 on a line by itself):
+
+ Line 1:  Real name
+ Line 2:  Street address or PO Box
+ Line 3:  City/town/village/etc.
+ Line 4:  State/province/etc.
+ Line 5:  ZIP Code
+ Line 6:  Telephone number
+ Line 7:  e-mail address
+ Line 8:  Country
+
+
+ CHEK   (CHEcK various things)
+
+ When logging in, there are various things that need to be checked.   This
+command will return ERROR+NOT_LOGGED_IN if no user is logged in.  Otherwise
+it returns OK and the following parameters:
+
+ 0: Number of new private messages in Mail>
+ 1: Nonzero if the user needs to register
+ 2: (Relevant to Aides only) Nonzero if new users require validation
+ 3: The user's preferred Internet e-mail address
+
+
+ DELF   (DELete a File)
+
+ This command deletes a file from the room's directory, if there is one.  The
+name of the file to delete is the only parameter to be supplied.  Wildcards
+are not acceptable, and any slashes in the filename will be converted to
+underscores, to prevent unauthorized access to neighboring directories.  The
+possible return codes are:
+
+ OK                            -  Command succeeded.  The file was deleted.
+ ERROR+NOT_LOGGED_IN           -  Not logged in.
+ ERROR+HIGHER_ACCESS_REQUIRED  -  Not an Aide or Room Aide.
+ ERROR+NOT_HERE                -  There is no directory in this room.
+ ERROR+FILE_NOT_FOUND          -  Requested file was not found.
+
+
+ MOVF   (MOVe a File)
+
+ This command is similar to DELF, except that it moves a file (and its
+associated file description) to another room.  It should be passed two
+parameters: the name of the file to move, and the name of the room to move
+the file to.  All of the same return codes as DELF may be returned, and also
+one additional one: ERROR+NO_SUCH_ROOM, which means that the target room
+does not exist.  ERROR+NOT_HERE could also mean that the target room does
+not have a directory.
+
+
+ NETF   (NETwork send a File)
+
+ This command is similar to MOVF, except that it attempts to send a file over
+the network to another system.  It should be passed two parameters: the name
+of the file to send, and the node name of the system to send it to.  All of
+the same return codes as MOVF may be returned, except for ERROR+NO_SUCH_ROOM.
+Instead, ERROR+NO_SUCH_SYSTEM may be returned if the name of the target
+system is invalid.
+
+ The name of the originating room will be sent along with the file.  Most
+implementations will look for a room with the same name at the receiving end
+and attempt to place the file there, otherwise it goes into a bit bucket room
+for miscellaneous files.  This is, however, beyond the scope of this document;
+see elsewhere for more details.
+
+
+ RWHO   (Read WHO's online)
+
+ Displays a list of all users connected to the server.  No error codes are
+ever returned.  LISTING_FOLLOWS will be returned, followed by zero or more
+lines containing the following three fields:
+
+ 0 - Session ID.  Citadel fills this with the pid of a server program.
+ 1 - User name.
+ 2 - The name of the room the user is currently in.  This field might not
+be displayed (for example, if the user is in a private room) or it might
+contain other information (such as the name of a file the user is
+downloading).
+ 3 - (server v4.03 and above) The name of the host the client is connecting
+from, or "localhost" if the client is local.
+ 4 - (server v4.04 and above) Description of the client software being used
+ 5 - The last time, locally to the server, that a command was received from
+     this client (Note: NOOP's don't count)
+ 6 - The last command received from a client. (NOOP's don't count)
+ 7 - Session flags.  These are: + (spoofed address), - (STEALTH mode), *
+     (posting) and . (idle).
+ 8 - Actual user name, if user name is masqueraded and viewer is an Aide.
+ 9 - Actual room name, if room name is masqueraded and viewer is an Aide.
+ 10 - Actual host name, if host name is masqueraded and viewer is an Aide.
+ 11 - Nonzero if the session is a logged-in user, zero otherwise.
+
+ The listing is terminated, as always, with the string "000" on a line by
+itself.
+
+
+ OPEN   (OPEN a file for download)
+
+ This command is used to open a file for downloading.  Only one download
+file may be open at a time.  The only argument to this command is the name
+of the file to be opened.  The user should already be in the room where the
+file resides.  Possible return codes are:
+
+ ERROR+NOT_LOGGED_IN
+ ERROR+NOT_HERE                (no directory in this room)
+ ERROR+FILE_NOT_FOUND          (could not open the file)
+ ERROR                         (misc errors)
+ OK                            (file is open)
+
+ If the file is successfully opened, OK will be returned, along with the
+size (in bytes) of the file, the time of last modification (if applicable),
+the filename (if known), and the MIME type of the file (if known).
+
+
+ CLOS   (CLOSe the download file)
+
+ This command is used to close the download file.  It returns OK if the
+file was successfully closed, or ERROR if there wasn't any file open in the
+first place.
+
+
+ READ   (READ from the download file)
+
+ Two arguments are passed to this command.  The first is the starting position
+in the download file, and the second is the total number of bytes to be
+read.  If the operation can be performed, BINARY_FOLLOWS will be returned,
+along with the number of bytes to follow.  Then, immediately following the
+newline, will be that many bytes of binary data.  The client *must* read
+exactly that number of bytes, otherwise the client and server will get out
+of sync.
+
+ If the operation cannot be performed, any of the usual error codes will be
+returned.
+
+
+ UOPN   (OPeN a file for Uploading)
+
+ This command is similar to OPEN, except that this one is used when the
+client wishes to upload a file to the server.  The first argument is the name
+of the file to create, and the second argument is a one-line comment
+describing the contents of the file.  Only one upload file may be open at a
+time.  Possible return codes are:
+
+ ERROR+NOT_LOGGED_IN
+ ERROR+NOT_HERE               (no directory in this room)
+ ERROR+FILE_NOT_FOUND         (a name must be specified)
+ ERROR                        (miscellaneous errors)
+ ERROR+ALREADY_EXISTS         (a file with the same name already exists)
+ OK
+
+ If OK is returned, the command has succeeded and writes may be performed.
+
+
+ UCLS   (CLoSe the Upload file)
+
+ Close the file opened with UOPN.  An argument of "1" should be passed to
+this command to close and save the file; otherwise, the transfer will be
+considered aborted and the file will be deleted.  This command returns OK
+if the operation succeeded or ERROR if it did not.
+
+
+ WRIT   (WRITe to the upload file)
+
+ If an upload file is open, this command may be used to write to it.  The
+argument passed to this command is the number of bytes the client wishes to
+transmit.  An ERROR code will be returned if the operation cannot be
+performed.
+
+ If the operation can be performed, SEND_BINARY will be returned, followed
+by the number of bytes the server is expecting.  The client must then transmit
+exactly that number of bytes.  Note that in the current implementation, the
+number of bytes the server is expecting will always be the number of bytes
+the client requested to transmit, but the client software should never assume
+that this will always happen, in case changes are made later.
+
+
+ QUSR   (Query for a USeR)
+
+ This command is used to check to see if a particular user exists.  The only
+argument to this command is the name of the user being searched for.  If
+the user exists, OK is returned, along with the name of the user in the userlog
+(so the client software can learn the correct upper/lower casing of the name
+if necessary).  If the user does not exist, ERROR+NO_SUCH_USER is returned.
+No login or current room is required to utilize this command.
+
+
+ OIMG   (Open an IMaGe file)
+
+ Open an image (graphics) file for downloading.  Once opened, the file can be
+read as if it were a download file.  This implies that an image and a download
+cannot be opened at the same time.  OIMG returns the same result codes as OPEN.
+
+ All images will be in GIF (Graphics Interchange Format).  In the case of
+Citadel, the server will convert the supplied filename to all lower case,
+append the characters ".gif" to the filename, and look for it in the "images"
+subdirectory.  As with the MESG command, there are several "well known"
+images which are likely to exist on most servers:
+
+ hello        - "Welcome" graphics to be displayed alongside MESG "hello"
+ goodbye      - Logoff banner graphics to be displayed alongside MESG "goodbye"
+ background   - Background image (usually tiled) for graphical clients
+
+ The following "special" image names are defined in Citadel server version
+5.00 and above:
+
+ _userpic_    - Picture of a user (send the username as the second argument)
+ _floorpic_   - A graphical floor label (send the floor number as the second
+                argument).  Clients which request a floor picture will display
+                the picture *instead* of the floor name.
+ _roompic_    - A graphic associated with the *current* room.  Clients which
+                request a room picture will display the picture in *addition*
+                to the room name (i.e. it's used for a room banner, as
+                opposed to the floor picture's use in a floor listing).
+
+
+ NETP   (authenticate as network session with connection NET Password)
+
+ This command is used by client software to identify itself as a transport
+session for IGnet/Open BBS to BBS networking.  It should be called with
+two arguments: the node name of the calling system, and the "shared secret"
+password for that connection.  If the authentication succeeds, NETP will
+return OK, otherwise, it returns ERROR.
+
+ NSYN   (Network SYNchronize room)
+ This command can be used to synchronize the contents of a room on the
+network.  It is only usable by Aides.  It accepts one argument: the name of
+a network node (which must be a valid one).
+ When NSYN is run, the *entire* contents of the current room will be spooled
+to the specified node, without regard to whether any of the messages have
+already undergone network processing.  It is up to the receiving node to
+check for duplicates (the Citadel networker does handle this) and avoid
+posting them twice.
+ The command returns OK upon success or ERROR if the user is not an Aide.
+  
+ NUOP   (Network Upload OPen file)
+
+ Open a network spool file for uploading.  The client must have already
+identified itself as a network session using the NETP command.  If the command
+returns OK, the client may begin transmitting IGnet/Open spool data using
+a series of WRIT commands.  When a UCLS command is issued, the spooled data
+is entered into the BBS if the argument to UCLS is 1 or discarded if the
+argument to UCLS is 0.  If the client has not authenticated itself with a
+NETP command, ERROR+HIGHER_ACCESS_REQUIRED will be returned.
+
+
+ NDOP   (Network Download OPen file)
+
+ Open a network spool file for downloading.  The client must have already
+identified itself as a network session using the NETP command.  If the command
+returns OK, the client may begin receiving IGnet/Open spool data using
+a series of READ commands.  When a CLOS command is issued, the spooled data
+is deleted from the server and may not be read again.  If the client has not
+authenticated itself with a NETP command, ERROR+HIGHER_ACCESS_REQUIRED will
+be returned.
+
+
+ LFLR   (List all known FLooRs)
+
+ On systems supporting floors, this command lists all known floors.  The
+command accepts no parameters.  It will return ERROR+NOT_LOGGED_IN if no
+user is logged in.  Otherwise it returns LISTING_FOLLOWS and a list of
+the available floors, each line consisting of three fields:
+
+ 1. The floor number associated with the floor
+ 2. The name of the floor
+ 3. Reference count (number of rooms on this floor)
+
+
+ CFLR   (Create a new FLooR)
+
+ This command is used to create a new floor.  It should be passed two
+arguments: the name of the new floor to be created, and a 1 or 0 depending
+on whether the client is actually creating a floor or merely checking to
+see if it has permission to create the floor.   The user must be logged in
+and have Aide privileges to create a floor.
+
+ If the command succeeds, it will return OK followed by the floor number
+associated with the new floor.  Otherwise, it will return ERROR (plus perhaps
+HIGHER_ACCESS_REQUIRED, ALREADY_EXISTS, or INVALID_FLOOR_OPERATION)
+followed by a description of why the command failed.
+
+
+ KFLR   (Kill a FLooR)
+
+ This command is used to delete a floor.  It should be passed two
+argument: the *number* of the floor to be deleted, and a 1 or 0 depending
+on whether the client is actually deleting the floor or merely checking to
+see if it has permission to delete the floor.  The user must be logged in
+and have Aide privileges to delete a floor.
+
+ Floors that contain rooms may not be deleted.  If there are rooms on a floor,
+they must be either deleted or moved to different floors first.  This implies
+that the Main Floor (floor 0) can never be deleted, since Lobby>, Mail>, and
+Aide> all reside on the Main Floor and cannot be deleted.
+
+ If the command succeeds, it will return OK.  Otherwise it will return
+ERROR (plus perhaps HIGHER_ACCESS_REQUIRED or INVALID_FLOOR_OPERATION)
+followed by a description of why the command failed.
+
+
+ EFLR   (Edit a FLooR)
+
+ Edit the parameters of a floor.  The client may pass one or more parameters
+to this command:
+
+ 1. The number of the floor to be edited
+ 2. The desired new name
+
+ More parameters may be added in the future.  Any parameters not passed to
+the server will remain unchanged.  A minimal command would be EFLR and a
+floor number -- which would do nothing.  EFLR plus the floor number plus a
+floor name would change the floor's name.
+
+ If the command succeeds, it will return OK.  Otherwise it will return
+ERROR (plus perhaps HIGHER_ACCESS_REQUIRED or INVALID_FLOOR_OPERATION)
+
+
+IDEN (IDENtify the client software)
+
+ The client software has the option to identify itself to the server.
+Currently, the server does nothing with this information except to write
+it to the syslog to satisfy the system administrator's curiosity.  Other
+uses might become apparent in the future.
+
+ The IDEN command should contain five fields: a developer ID number (same as
+the server developer ID numbers in the INFO command -- please obtain one if
+you are a new developer), a client ID number (which does not have to be
+globally unique - only unique within the domain of the developer number),
+a version number, a free-form text string describing the client, and the name
+of the host the user is located at.
+
+ It is up to the server to determine whether to accept the host name or to
+use the host name it has detected itself.  Generally, if the client is
+running on a trusted host (either localhost or a well-known publically
+accessible client) it should use the host name transmitted by IDEN,
+otherwise it should use the host name it has detected itself.
+
+ IDEN always returns OK, but since that's the only way it ever returns
+there's no point in checking the result code.
+
+
+IPGM (identify as an Internal ProGraM)
+
+ IPGM is a low-level command that should not be used by normal user clients.
+It is used for various utilities to communicate with the server on the same
+host.  For example, the "sendcommand" utility logs onto the server as an
+internal program in order to run arbitrary server commands.  Since user clients
+do not utilize this command (or any of its companion commands), developers
+writing Citadel-compatible servers need not implement it.
+
+ The sole argument to IPGM is the system's internal program password.  This
+password is generated by the setup program and stored in the config file.
+Since internal programs have access to the config file, they know the correct
+password to use.
+
+ IPGM returns OK for a correct authentication or ERROR otherwise.
+
+
+CHAT (enter CHAT mode)
+
+ This command functions differently from every other command in the system.  It
+is used to implement multi-user chat.  For this to function, a new transfer
+mode, called START_CHAT_MODE, is implemented.  If a client does not support
+chat mode, it should never send a CHAT command!
+
+ In chat mode, messages may arrive asynchronously from the server at any
+time.  The client may send messages at any time.  This allows the arrival of
+messages without the client having to poll for them.  Arriving messages will
+be of the form  "user|message", where the "user" portion is, of course, the
+name of the user sending the message, and "message" is the message text.
+
+ Chat mode ends when the server says it ends.  The server will signal the end
+of chat mode by transmitting "000" on a line by itself.  When the client reads
+this line, it must immediately exit from chat mode without sending any
+further traffic to the server.  The next transmission sent to the server
+will be a regular server command.
+
+ The Citadel server understands the following commands:
+ /quit   -   Exit from chat mode (causes the server to do an 000 end)
+ /who    -   List users currently in chat
+ /whobbs -   List users currently in chat and on the bbs
+ /me     -   Do an irc-style action.
+ /join   -   Join a new "room" in which all messages are only heard by
+             people in that room.
+ /msg    -   /msg <user> <msg> will send the msg to <user> only.
+ /help   -   Print help information
+ NOOP    -   Do nothing (silently)
+
+ Any other non-empty string is treated as message text and will be broadcast
+to other users currently in chat.
+
+
+ SEXP   (Send instant message)
+
+ This is one of two commands which implement instant messages (also known
+as "paging").  Commands ending in "...EXP" are so-named because we called
+them "express messages" before the industry standardized on the term
+"instant messages."  When an instant message is sent, it will be
+logged in user to another.  When an instant message is sent, it will be
+displayed the next time the target user executes a PEXP or GEXP command.
+
+ The SEXP command accepts two arguments: the name of the user to send the
+message to, and the text of the message.  If the message is successfully
+transmitted, OK is returned.  If the target user is not logged in or if
+anything else goes wrong, ERROR is returned.
+
+ If the server supports extended paging, sending a zero-length message
+merely checks for the presence of the requested user without actually sending
+a message.  Sending a message consisting solely of a "-" (hyphen) will cause
+the server to return SEND_LISTING if the requested user is logged in, and the
+client can then transmit a multi-line page.
+
+ The reserved name "broadcast" may be used instead of a user name, to
+broadcast an instant message to all users currently connected to the server.
+
+ Do be aware that if an instant message is transmitted to a user who is logged
+in using a client that does not check for instant messages, the message will
+never be received.  Also, instant messages are NOT sent via the following
+transports:  SMTP, POP3.
+
+
+ PEXP   (Print instant messages)   ***DEPRECATED***
+
+ This command is deprecated; it will eventually disappear from the protocol and
+its use is not recommended.  Please use the GEXP command instead.
+
+ Called without any arguments, PEXP simply dumps out the contents
+of any waiting instant messages.  It returns ERROR if there is a problem,
+otherwise it returns LISTING_FOLLOWS followed by all messages.
+
+ So how does the client know there are instant messages waiting?  It could
+execute a random PEXP every now and then.  Or, it can check the byte in
+server return code messages, between the return code and the parameters.  In
+much the same way as FTP uses "-" to signify a continuation, Citadel uses
+an "*" in this position to signify the presence of waiting instant messages.
+
+
+ EBIO   (Enter BIOgraphy)
+
+ Transmit to the server a free-form text file containing a little bit of
+information about the user for other users to browse.  This is typically
+referred to as a 'bio' online.  EBIO returns SEND_LISTING if it succeeds,
+after which the client is expected to transmit the file, or any of the usual
+ERROR codes if it fails.
+
+
+ RBIO   (Read BIOgraphy)
+
+ Receive from the server a named user's bio.  This command should be passed
+a single argument - the name of the user whose bio is requested.  RBIO returns
+LISTING_FOLLOWS plus the bio file if the user exists and has a bio on file.
+The return has the following parameters:  the user name, user number, access
+level, date of last call, times called, and messages posted.  This command
+returns ERROR+NO_SUCH_USER if the named user does not exist.
+
+ RBIO no longer considers a user with no bio on file to be an error condition.
+It now returns a message saying the user has no bio on file as the text of the
+bio.  This allows newer servers to operate with older clients.
+
+
+ STEL   (enter STEaLth mode)
+
+ When in "stealth mode," a user will not show up in the "Who is online"
+listing (the RWHO server command).  Only Aides may use stealth mode.  The
+STEL command accepts one argument: a 1 indicating that the user wishes to
+enter stealth mode, or a 0 indicating that the user wishes to exit stealth
+mode.  STEL returns OK if the command succeeded, ERROR+NOT_LOGGED_IN if no
+user is logged in, or ERROR+HIGHER_ACCESS_REQUIRED if the user is not an Aide;
+followed by a 1 or 0 indicating the new state.
+
+ If any value other than 1 or 0 is sent by the client, the server simply
+replies with 1 or 0 to indicate the current state without changing it.
+
+The STEL command also makes it so a user does not show up in the chat room
+/who.
+
+
+ LBIO   (List users who have BIOs on file)
+
+ This command is self-explanatory.  Any user who has used EBIO to place a bio
+on file is listed.  LBIO almost always returns LISTING_FOLLOWS followed by
+this listing, unless it experiences an internal error in which case ERROR
+is returned.
+
+
+ MSG2   (read MeSsaGe, mode 2)
+
+ MSG2 follows the same calling convention as MSG0.  The difference between
+the two commands is that MSG2 outputs messages in standard RFC822 format
+rather than in Citadel proprietary format.
+
+ This command was implemented in order to make various gateway programs
+easier to implement, and to provide some sort of multimedia support in the
+future.  Keep in mind that when this command is used, all messages will be
+output in fixed 80-column format.
+
+
+ MSG3   (read MeSsaGe, mode 3 -- internal command)
+
+ 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.
+
+
+ TERM   (TERMinate another session)
+
+ In a multithreaded environment, it sometimes becomes necessary to terminate
+a session that is unusable for whatever reason.  The TERM command performs
+this task.  Naturally, only Aides can execute TERM.  The command should be
+called with a single argument: the session ID (obtained from an RWHO command)
+of the session to be terminated.
+
+ TERM returns OK if the session was terminated, or ERROR otherwise.  Note that
+a client program is prohibited from terminating the session it is currently
+running on.
+
+ See also: REQT
+
+
+ DOWN   (shut DOWN the server)
+
+ This command, which may only be executed by an Aide, immediately shuts down
+the server.  It is only implemented on servers on which such an operation is
+possible, such as a multithreaded Citadel engine.  The server does not restart.
+DOWN returns OK if the user is allowed to shut down the server, in which case
+the client program should expect the connection to be immediately broken.
+
+
+ SCDN   (Schedule or Cancel a shutDowN)
+
+ SCDN sets or clears the "scheduled shutdown" flag.  Pass this command a 1 or
+0 to respectively set or clear the flag.  When the "scheduled shutdown" flag is
+set, the server will be shut down when there are no longer any users logged in.
+Any value other than 0 or 1 will not change the flag, only report its state.
+No users will be kicked off the system, and in fact the server is still
+available for new connections.  The command returns ERROR if it fails;
+otherwise, it returns OK followed by a number representing the current state
+of the flag.
+
+
+ EMSG   (Enter a system MeSsaGe)
+
+ 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.
+
+
+ UIMG   (Upload an IMaGe file)
+
+ UIMG is complemenary to OIMG; it is used to upload an image to the server.
+The first parameter supplied to UIMG should be 0 if the client is only checking
+for permission to upload, or 1 if the client is actually attempting to begin
+the upload operation.  The second argument is the name of the file to be
+transmitted.  In Citadel, the filename is converted to all lower case,
+appended with the characters ".gif", and stored in the "images" directory.
+
+ UIMG returns OK if the client has permission to perform the requested upload,
+or ERROR+HIGHER_ACCESS_REQUIRED otherwise.  If the client requested to begin
+the operation (first parameter set to 1), an upload file is opened, and the
+client should begin writing to it with WRIT commands, then close it with a
+UCLS command.
+
+ The supplied filename should be one of:
+
+ ->  _userpic_   (Server will attempt to write to the user's online photo)
+ ->  Any of the "well known" filenames described in the writeup for the
+     OIMG command.
+
+
+ HCHG  (Hostname CHanGe)
+
+ HCHG is a command, usable by any user, that allows a user to change their RWHO
+host value.  This will mask a client's originating hostname from normal
+users; access level 6 and higher can see, in an extended wholist, the actual
+hostname the user originates from.
+
+ The format of an HCHG command is:
+
+ HCHG <name>
+
+ If a HCHG command is successful, the value OK (200) is returned.
+
+
+ RCHG  (Roomname CHanGe)
+
+ RCHG is a command, usable by any user, that allows a user to change their RWHO
+room value.  This will mask a client's roomname from normal users; access
+level 6 and higher can see, in an extended wholist, the actual room the user
+is in.
+
+ The format of an RCHG command is:
+
+ RCHG <name>
+
+ If a RCHG command is successful, the value OK (200) is returned.
+
+
+ UCHG  (Username CHanGe)
+
+ UCHG is an aide-level command which allows an aide to effectively change their
+username.  If this value is blank, the user goes into stealth mode (see
+STEL).  Posts
+will show up as being from the real username in this mode, however.  In
+addition, the RWHO listing will include both the spoofed and real usernames.
+
+ The format of an UCHG command is:
+
+ UCHG <name>
+
+ If a UCHG command is successful, the value OK (200) is returned.
+
+
+ TIME  (get server local TIME)
+
+ TIME returns OK followed by the current time measured in seconds since
+00:00:00 GMT, Jan 1, 1970 (standard Unix format).
+
+ This is used in allowing a client to calculate idle times.
+
+
+ AGUP   (Administrative Get User Parameters)
+ ASUP   (Administrative Set User Parameters)
+
+ These commands are only executable by Aides and by server extensions running
+at system-level.  They are used to get/set any and all parameters relating to
+a user account.  AGUP requires only one argument: the name of the user in
+question.  SGUP requires all of the parameters to be set.  The parameters are
+as follows, and are common to both commands:
+
+ 0 - User name
+ 1 - Password
+ 2 - Flags (see citadel.h)
+ 3 - Times called
+ 4 - Messages posted
+ 5 - Access level
+ 6 - User number
+ 7 - Timestamp of last call
+ 8 - Purge time (in days) for this user (or 0 to use system default)
+
+ Upon success, AGUP returns OK followed by all these parameters, and ASUP
+simply returns OK.  If the client has insufficient access to perform the
+requested operation, ERROR+HIGHER_ACCESS_REQUIRED is returned.  If the
+requested user does not exist, ERROR+NO_SUCH_USER is returned.
+
+
+
+ GPEX   (Get Policy for message EXpiration)
+
+ Returns the policy of the current room, floor, or site regarding the automatic
+purging (expiration) of messages.  The following policies are available:
+   0  -  Fall back to the policy of the next higher level.  If this is a room,
+         use the floor's default policy.  If this is a floor, use the system
+         default policy.  This is an invalid value for the system policy.
+   1  -  Do not purge messages automatically.
+   2  -  Purge by message count.  (Requires a value: number of messages)
+   3  -  Purge by message age.  (Requires a value: number of days)
+
+ The format of this command is:  GPEX <which>
+ The value of <which> must be one of: "room" "floor" "site" "mailboxes"
+
+ If successful, GPEX returns OK followed by <policy>|<value>.
+
+
+
+ SPEX   (Set Policy for message EXpiration)
+
+ Sets the policy of the current room, floor, or site regarding the automatic
+purging (expiration) of messages.  See the writeup for the GPEX command for
+the list of available policies.
+
+ The format of this command is:  SPEX <which>|<policy>|<value>
+ The value of <which> must be one of: "room" "floor" "site" "mailboxes"
+
+ If successful, GPEX returns OK; otherwise, an ERROR code is returned.
+
+
+
+ CONF   (get or set global CONFiguration options)
+
+ Retrieves or sets various system-wide configuration and policy options.  This
+command is only available to Aides.  The sole parameter accepted is a command,
+which should be either GET or SET.  If the GET command succeeds, CONF will
+return LISTING_FOLLOWS followed by the fields described below, one line at a
+time.  If the SET command succeeds, CONF will return SEND_LISTING and expect
+the fields described below, one line at a time (don't worry about other fields
+being added in the future; if a 'short' configuration list is sent, the missing
+values at the end will be left unchanged on the system).  If either command
+fails for any reason, ERROR is returned.
+
+ The configuration lines are as follows:
+
+ 1. Node name
+ 2. Fully qualified domain name
+ 3. Human-readable node name
+ 4. Landline telephone number of this system
+ 5. Flag (0 or 1) - creator of private room automatically becomes room aide
+ 6. Server connection idle timeout (in seconds)
+ 7. Initial access level for new users
+ 8. Flag (0 or 1) - require registration for new users
+ 9. Flag (0 or 1) - automatically move Problem User messages to twit room
+ 10. Name of twit room
+ 11. Text of <more> prompt
+ 12. Flag (0 or 1) - restrict access to Internet mail
+ 13. Geographic location of this system
+ 14. Name of the system administrator
+ 15. Number of maximum concurrent sessions allowed on the server
+ 16. (placeholder -- this field is no longer in use)
+ 17. Default purge time (in days) for users
+ 18. Default purge time (in days) for rooms
+ 19. Name of room to log instant messages to (or a zero-length name for none)
+ 20. Access level required to create rooms
+ 21. Maximum message length which may be entered into the system
+ 22. Minimum number of worker threads
+ 23. Maximum number of worker threads
+ 24. Port number for POP3 service
+ 25. Port number for SMTP service
+ 26. Flag (0 or 1) - strict RFC822 adherence - don't correct From: forgeries
+ 27. Flag (0 or 1) - allow Aides to zap (forget) rooms
+ 28. Port number for IMAP service
+ 29. How often (in seconds) to run the networker
+ 30. Flag (0 or 1) - disable self-service new user registration
+ 31. (placeholder -- this field is no longer in use)
+ 32. Hour (0 through 23) during which database auto-purge jobs are run
+ 33. Name of host where an LDAP service may be found
+ 34. Port number of LDAP service on above host
+ 35. LDAP Base DN
+ 36. LDAP Bind DN
+ 37. Password for LDAP Bind DN
+ 38. Server IP address to listen on (or "0.0.0.0" for all addresses)
+
+ CONF also accepts two additional commands: GETSYS and PUTSYS followed by an
+arbitrary MIME type (such as application/x-citadel-internet-config) which
+provides a means of storing generic configuration data in the Global System
+Configuration room without the need to add extra get/set commands to the
+server.
+ Please note that the LDAP-specific configs have no effect on Citadel servers
+in which LDAP support is not enabled.
+
+
+
+ MSG4   (read MeSsaGe, mode 4 -- output in preferred MIME format)
+
+ 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.
+
+
+
+ MSGP   (set MeSsaGe Preferred MIME format)
+
+ 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:  MSGP text/html|text/plain
+
+ The MSGP command always returns OK.
+
+
+
+ OPNA   (OPeN Attachment)
+
+ 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.
+
+
+ GEXP   (Get instant messages)
+
+ This is a more sophisticated way of retrieving instant messages than the old
+PEXP method.  If there are no instant messages waiting, PEXP returns ERROR;
+otherwise, it returns LISTING_FOLLOWS and the following arguments:
+
+ 0 - a boolean value telling the client whether there are any additional
+     instant messages waiting following this one
+ 1 - a Unix-style timestamp
+ 2 - flags (see server.h for more info)
+ 3 - the name of the sender
+ 4 - the node this message originated on (for future support of PIP, ICQ, etc.)
+
+ The text sent to the client will be the body of the instant message.
+
+ So how does the client know there are instant messages waiting?  It could
+execute a random GEXP every now and then.  Or, it can check the byte in
+server return code messages, between the return code and the parameters.  In
+much the same way as FTP uses "-" to signify a continuation, Citadel uses
+an "*" in this position to signify the presence of waiting instant messages.
+
+
+ FSCK   (check message base reference counts)
+
+ Verify, via the long way, that all message referenmce counts are correct.  If
+the user has permission to do this then LISTING_FOLLOWS is returned, followed
+by a transcript of the run.  Otherwise ERROR is returned.
+
+
+ DEXP   (Disable receiving instant messages)
+
+ DEXP sets or clears the "disable instant messages" flag.  Pass this command a
+1 or 0 to respectively set or clear the flag.  When the "disable instant
+messages" flag is set, no one except Aides may send the user instant messages.
+Any value other than 0 or 1 will not change the flag, only report its state.
+The command returns ERROR if it fails; otherwise, it returns OK followed by a
+number representing the current state of the flag.
+
+
+ REQT   (REQuest client Termination)
+
+ Request that the specified client (or all clients) log off.  Aide level
+access is required to run this command, otherwise ERROR+HIGHER_ACCESS_REQUIRED
+is returned.
+
+ The REQT command accepts one parameter: the session ID of the client which
+should be terminated, or 0 for all clients.  When successful, the REQT command
+returns OK.
+
+ It should be noted that REQT simply transmits an instant message to the
+specified client(s) with the EM_GO_AWAY flag set.  Older clients do not honor
+this flag, and it is certainly possible for users to re-program their client
+software to ignore it.  Therefore the effects of the REQT command should be
+considered advisory only.  The recommended implementation practice is to first
+issue a REQT command, then wait a little while (from 30 seconds up to a few
+minutes) for well-behaved clients to voluntarily terminate, and then issue a
+TERM command to forcibly disconnect the client (or perhaps a DOWN command, if
+you are logging off users for the purpose of shutting down the server).
+
+
+ SEEN   (set or clear the SEEN flag for a message)
+
+ 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.
+
+
+ GTSN   (GeT the list of SeeN messages)
+
+ 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.
+
+
+ SMTP   (utility commands for the SMTP gateway)
+
+ This command, accessible only by Aides, supports several utility operations
+which examine or manipulate Citadel's SMTP support.  The first command argument
+is a subcommand telling the server what to do.  The following subcommands are
+supported:
+
+      SMTP mx|hostname             (display all MX hosts for 'hostname')
+      SMTP runqueue                (attempt immediate delivery of all messages
+                                    in the outbound SMTP queue, ignoring any
+                                    retry times stored there)
+
+
+ STLS   (Start Transport Layer Security)
+
+ This command starts TLS on the current connection.  The current
+implementation uses OpenSSL on both the client and server end.  For future
+compatibility all clients must support at least TLSv1, and servers are
+guaranteed to support TLSv1.  During TLS negotiation (see below) the server
+and client may agree to use a different protocol.
+
+ The server returns ERROR if it does not support SSL or SSL initialization
+failed on the server; otherwise it returns OK.  Once the server returns OK and
+the client has read the response, the server and client immediately negotiate
+TLS (in OpenSSL, using SSL_connect() on the client and SSL_accept() on the
+server).  If negotiation fails, the server and client should attempt to resume
+the session unencrypted.  If either end is unable to resume the session, the
+connection should be closed.
+
+ This command may be run at any time.
+
+
+ GTLS   (Get Transport Layer Security Status)
+
+ This command returns information about the current connection.  The server
+returns OK plus several parameters if the connection is encrypted, and ERROR
+if the connection is not encrypted.  It is primarily used for debugging.  The
+command may be run at any time.
+
+ 0 - Protocol name, e.g. "SSLv3"
+ 1 - Cipher suite name, e.g. "ADH-RC4-MD5"
+ 2 - Cipher strength bits, e.g. 128
+ 3 - Cipher strength bits actually in use, e.g. 128
+
+
+ IGAB   (Initialize Global Address Book)
+
+ This command creates, or re-creates, a database of Internet e-mail addresses
+using the vCard information in the Global Address Book room.  This procedure
+is normally run internally when the server determines it necessary, but is
+also provided as a server command to be used as a troubleshooting/maintenenance
+tool.  Only a system Aide can run the command.  It returns OK on success or
+ERROR on failure.
+
+
+ QDIR   (Query global DIRectory)
+
+ Look up an internet address in the global directory.  Any logged-in user may
+call QDIR with one parameter, the Internet e-mail address to look up.  QDIR
+returns OK followed by a Citadel address if there is a match, otherwise it
+returns ERROR+NOT_LOGGED_IN.
+
+
+ ISME   (find out if an e-mail address IS ME)
+
+ This is a quickie shortcut command to find out if a given e-mail address
+belongs to the user currently logged in.  Its sole argument is an address to
+parse.  The supplied address may be in any format (local, IGnet, or Internet).
+The command returns OK if the address belongs to the user, ERROR otherwise.
+
+
+ VIEW   (set the VIEW for a room)
+
+ 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.
+
+
+ QNOP   (Quiet No OPeration)
+
+ This command does nothing, similar to the NOOP command.  However, unlike the
+NOOP command, it returns *absolutely no response* at all.  The client has no
+way of knowing that the command executed.  It is intended for sending
+"keepalives" in situations where a full NOOP would cause the client protocol
+to get out of sync.
+
+ Naturally, sending this command to a server that doesn't support it is an
+easy way to mess things up.  Therefore, client software should first check
+the output of an INFO command to ensure that the server supports quiet noops.
+
+
+
+ ICAL   (Internet CALendaring commands)
+
+ This command supports a number of subcommands which are used to process the
+calendaring/scheduling support in Citadel.  Here are the subcommands which
+may be issued:
+
+ ICAL test
+  Test server for calendaring support.  Always returns OK unless the server
+  does not have the calendar module enabled.
+
+ ICAL respond|msgnum|partnum|action
+  Respond to a meeting request.  'msgnum' and 'partnum' refer to a MIME-encoded
+  meeting invitation in the current room.  'action' must be set to either
+  "accept" or "decline" to determine the action to take.  This subcommand will
+  return either OK or ERROR.
+
+ ICAL conflicts|msgnum|partnum
+  Determine whether an incoming VEVENT will fit in the user's calendar by
+  checking it against the existing VEVENTs.  'msgnum' and 'partnum' refer to
+  a MIME-encoded meeting invitation in the current room (usually the inbox).
+  This command may return ERROR if something went wrong, but usually it will
+  return LISTING_FOLLOWS followed by a list of zero or more conflicting
+  events.  A zero-length list means that there were no conflicts.
+ ICAL handle_rsvp|msgnum|partnum
+  Handle an incoming "reply" (or RSVP) to a meeting request you sent out.
+  'msgnum' and 'partnum' refer to a MIME-encoded reply in the current room.
+  'action' must be set to either "update" or "ignore" to determine the action
+  to take.  If the action is "update" then the server will hunt for the meeting
+  in the user's Calendar> room, and update the status for this attendee.  Either
+  way, the reply message is deleted from the current room.  This subcommand will
+  return either OK or ERROR.
+ ICAL freebusy|username
+  Output the free/busy times for the requested user.  If the user specified
+  has a calendar available, this command will return LISTING_FOLLOWS and a
+  compound VCALENDAR object.  That object, in turn, will contain VEVENT
+  objects that have been stripped of all properties except for the bare
+  minimum needed to learn free/busy times (such as DTSTART, DTEND, and
+  TRANSP).  If there is no such user, or no calendar available, the usual
+  ERROR codes will be returned.
+ ICAL sgi|<bool>
+ Readers who are paying attention will notice that there is no subcommand to
+send out meeting invitations.  This is because that task can be handled
+automatically by the Citadel server.  Issue this command with <bool> set to 1
+to enable Server Generated Invitations.  In this mode, when an event is saved
+to the user's Calendar> room and it contains attendees, Citadel will
+automatically turn the event into vCalendar REQUEST messages and mail them
+out to all listed attendees.  If for some reason the client needs to disable
+Server Generated Invitations, the command may be sent again with <bool> = 0.
+
+
+
+ MRTG   (Multi Router Traffic Grapher)
+
+ Multi Router Traffic Grapher (please see http://www.mrtg.org for more info) is
+a tool which creates pretty graphs of network activity, usually collected from
+routers using SNMP.  However, its ability to call external scripts has spawned
+a small community of people using it to graph anything which can be graphed.
+The MRTG command can output Citadel server activity in the format MRTG expects.
+
+ This format is as follows:
+
+ LISTING_FOLLOWS
+ Line 1: variable #1
+ Line 2: variable #2
+ Line 3: uptime of system
+ Line 4: name of system
+ 000
+
+ MRTG accepts two different keywords.  "MRTG users" will return two variables,
+the number of connected users and the number of active users.  "MRTG messages"
+will return one variable (and a zero in the second field), showing the current
+highest message number on the system.  Any other keyword, or a missing keyword,
+will cause the MRTG command to return an ERROR code.
+
+ Please get in touch with the Citadel developers if you wish to experiment with
+this.
+
+
+
+ GNET   (Get NETwork configuration for this room)
+ SNET   (Set NETwork configuration for this room)
+ These commands get/set the network configuration for the current room.  Aide
+or Room Aide privileges are required, otherwise an ERROR code is returned.
+If the command succeeds, LISTING_FOLLOWS or SEND_LISTING is returned.  The
+network configuration for a specific room includes neighbor nodes with whom
+the room is shared, and mailing list recipients.  The format of the network
+configuration is described in the file "netconfigs.txt".
+
+
+
+ ASYN   (ASYNchronous message support)
+
+ Negotiate the use of asynchronous, or unsolicited, protocol messages.  The
+only parameter specified should be 1 or 0 to indicate that the client can or
+cannot handle this type of messages.  The server will reply OK followed by a
+1 or 0 to tell the client which mode it is now operating in.
+
+ If the command is not available on the server (i.e. it returns ERROR), or
+if the command has not been executed by the client, it should be assumed that
+this mode of operation is NOT in effect.
+
+ The client may also send any value other than 0 or 1 to simply cause the
+server to output its current state without changing it.
+
+ When asynchronous protocol mode is in effect, the client MUST handle any
+asynchronous messages as they arrive, before doing anything else.
+
+
+
+
+ ASYNCHRONOUS MESSAGES
+ ---------------------
+
+ When the client protocol is operating in asynchronous mode (please refer to
+the writeup of the ASYN command above), the following messages may arrive at
+any time:
+
+
+ 902  (instant message arriving)
+
+ One or more instant messages have arrived for this client.
diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt
deleted file mode 100644 (file)
index a6b7573..0000000
+++ /dev/null
@@ -1,2143 +0,0 @@
-                SESSION LAYER PROTOCOL FOR THE CITADEL SYSTEM
-         (c) 1995-2004 by Art Cancro et. al.    All Rights Reserved
-
-
- INTRODUCTION
- ------------
-
- This is an attempt to document the session layer protocol used by the
-Citadel system, beginning with version 4.00, which is the first version
-to implement a client/server paradigm.  It is intended as a resource for
-programmers who intend to develop their own Citadel clients, but it may have
-other uses as well.
-
-
- IMPORTANT NOTE TO DEVELOPERS!
- -----------------------------
-
- Anyone who wants to add commands or other functionality to this protocol,
-*please* get in touch so that these efforts can be coordinated.  New
-commands added by other developers can be added to this document, so we
-don't end up with new server commands from multiple developers which have
-the same name but perform different functions.  If you don't coordinate new
-developments ahead of time, please at least send in an e-mail documenting
-what you did, so that your new commands can be added to this document.
-
- The coordinator of the Citadel project is Art Cancro
-<ajc@uncensored.citadel.org>.
-
-
- CONNECTING TO A SERVER
- ----------------------
-
- The protocols used below the session layer are beyond the scope of this
-document, but we will briefly cover the methodology employed by Citadel.
-
- Citadel offers Citadel BBS service using TCP/IP.  It does so via a
-multithreaded server listening on a TCP port.  Local connections may also
-be made using the same protocol using Unix domain sockets.
-
- The port number officially assigned to Citadel by the IANA is 504/tcp.  Since
-our session layer assumes a clean, reliable, sequenced connection, the use
-of UDP would render the server unstable and unusable, so we stick with TCP.
-
-
- GENERAL INFORMATION ABOUT THE SERVER
- ------------------------------------
-
- The server is connection-oriented and stateful: each client requires its own
-connection to a server process, and when a command is sent, the client must
-read the response, and then transfer data or change modes if necessary.
-
- The session layer is very much like other Internet protocols such as SMTP
-or NNTP.  A client program sends one-line commands to the server, and the
-server responds with a three-digit numeric result code followed by a message
-describing what happened.  This cycle continues until the end of the
-session.
-
- Unlike protocols such as FTP, all data transfers occur in-band.  This means
-that the same connection that is used for exchange of client/server
-messages, will also be used to transfer data back and forth.  (FTP opens a
-separate connection for data transfers.)  This keeps protocol administration
-straightforward, as it can traverse firewalls without any special protocol
-support on the firewall except for opening the port number.
-
-
- RESULT CODES
- ------------
-
- The server will respond to all commands with a 3-digit result code, which
-will be the first three characters on the line.  The rest of the line may
-contain a human-readable string explaining what happened.  (Some client
-software will display some of these strings to the user.)
-
- The first digit is the most important.  The following codes are defined for
-this position: ERROR, OK, MORE_DATA, LISTING_FOLLOWS, and SEND_LISTING.
-
- The second and third digits may provide a reason as to why a command
-succeeded or failed.  See ipcdef.h for the available codes.
-
- ERROR means the command did not complete.
- OK means the command executed successfully.
- MORE_DATA means the command executed partially.  Usually this means that
-another command needs to be executed to complete the operation.  For example,
-sending the USER command to log in a user usually results in a MORE_DATA
-result code, because the client needs to execute a PASS command to send the
-password and complete the login.
- LISTING_FOLLOWS means that after the server response, the server will
-output a listing of some sort.  The client *must* read the listing, whether
-it wants to or not.  The end of the listing is signified by the string
-"000" on a line by itself.
- SEND_LISTING is the opposite of LISTING_FOLLOWS.  It means that the client
-should begin sending a listing of some sort.  The client *must* send something,
-even if it is an empty listing.  Again, the listing ends with "000" on a line
-by itself.
- BINARY_FOLLOWS and SEND_BINARY mean that the client must immediately send
-or receive a block of binary data.  The first parameter will always be the
-number of bytes.
- ASYNC_MESSAGE_FOLLOWS means that an asynchronous, or unsolicited, message
-follows.  The next line will be one of the above codes, and if a data transfer
-is involved it must be handled immediately.  Note that the client will not
-receive this type of response unless it indicates to the server that it is
-capable of handling them; see the writeup of the ASYN command later in this
-document.
-
- PARAMETERIZATION
- ----------------
-
- Zero or more parameters may be passed to a command.  When more than one
-parameter is passed to a command, they should be separated by the "|"
-symbol like this:
-  SETU 80|24|260
- In this example, we're using the "SETU" command and passing three
-parameters: 80, 24, and 260.
-
- When the server spits out data that has parameters, if more than one
-parameter is returned, they will be separated by the "|" symbol like
-this:
-  200 80|24|260
- In this example, we just executed the "GETU" command, and it returned us
-an OK result code (the '2' in the 200) and three parameters: 80, 24, and
-260.
-
-
- COMMANDS
- --------
-
- This is a listing of all the commands that a Citadel server can execute.
-
-
- NOOP   (NO OPeration)
-
- This command does nothing.  It takes no arguments and always returns
-OK.  It is intended primarily for testing and development, but it might also
-be used as a "keep alive" command to prevent the server from timing out, if
-it's running over a transport that needs this type of thing.
-
-
- ECHO   (ECHO something)
-
- This command also does nothing.  It simply returns OK followed by whatever
-its arguments are.
-
-
- QUIT   (QUIT)
-
- Terminate the server connection.  This command takes no arguments.  It
-returns OK and closes the connection immediately.
-
-
- LOUT   (LogOUT)
-
- Log out the user without closing the server connection.  It always returns
-OK even if no user is logged in.
-
-
- USER   (send USER name)
-
- The first step in logging in a user.  This command takes one argument: the
-name of the user to be logged in.  If the user exists, a MORE_DATA return
-code will be sent, which means the client should execute PASS as the next
-command.  If the user does not exist, ERROR + NO_SUCH_USER is returned.
-
-
- PASS   (send PASSword)
-
- The second step in logging in a user.  This command takes one argument: the
-password for the user we are attempting to log in.  If the password doesn't
-match the correct password for the user we specified for the USER command,
-ERROR + PASSWORD_REQUIRED is returned.  If a USER command has not been
-executed yet, ERROR + USERNAME_REQUIRED is returned.  If a user is already
-logged in, ERROR + ALREADY_LOGGED_IN is returned.  If the password is
-correct, OK is returned and the user is now logged in... and most of the
-other server commands can now be executed.  Along with OK, the following
-parameters are returned:
-
- 0 - The user's name (in case the client wants the right upper/lower casing)
- 1 - The user's current access level
- 2 - Times called
- 3 - Messages posted
- 4 - Various flags (see citadel.h)
- 5 - User number
- 6 - Time of last call (UNIX timestamp)
-
-
- NEWU   (create NEW User account)
-
- This command creates a new user account AND LOGS IT IN.  The argument to
-this command will be the name of the account.  No case conversion is done
-on the name.  Note that the new account is installed with a default
-configuration, and no password, so the client should immediately prompt the
-user for a password and install it with the SETP command as soon as this
-command completes.  This command returns OK if the account was created and
-logged in, ERROR + ALREADY_EXISTS if another user already exists with this
-name, ERROR + NOT_HERE if self-service account creation is disabled,
-ERROR + MAX_SESSIONS_EXCEEDED if too many users are logged in, ERROR +
-USERNAME_REQUIRED if a username was not provided, or ERROR + ILELGAL_VALUE
-if the username provided is invalid.  If OK, it will also return the same
-parameters that PASS returns.
-
- Please note that the NEWU command should only be used for self-service
-user account creation.  For administratively creating user accounts, please
-use the CREU command.
-
-
- SETP   (SET new Password)
-
- This command sets a new password for the currently logged in user.  The
-argument to this command will be the new password.  The command always
-returns OK, unless the client is not logged in, in which case it will return
-ERROR + NOT_LOGGED_IN, or if the user is an auto-login user, in which case
-it will return ERROR + NOT_HERE.
-
-
- CREU   (CREate new User account)
-
- This command creates a new user account AND DOES NOT LOG IT IN.  The first
-argument to this command will be the name of the account.  No case conversion
-is done on the name.  Note that the new account is installed with a default
-configuration, and no password.  The second argument is optional, and will be
-an initial password for the user.  This command returns OK if the account was
-created, ERROR + HIGHER_ACCESS_REQUIRED if the user is not an Aide, ERROR +
-USERNAME_REQUIRED if no username was specified, or ERROR + ALREADY_EXISTS if
-another user already exists with this name.
-
- Please note that CREU is intended to be used for activities in which a
-system administrator is creating user accounts.  For self-service user
-account creation, use the NEWU command.
-
-
- LKRN   (List Known Rooms with New messages)
-
- List known rooms with new messages.  If the client is not logged in, ERROR +
-NOT_LOGGED_IN is returned.  Otherwise, LISTING_FOLLOWS is returned, followed
-by the room listing.  Each line in the listing contains the full name of a
-room, followed by the '|' symbol, and then a number that may contain the
-following bits:
-
-#define QR_PERMANENT   1               /* Room does not purge              */
-#define QR_PRIVATE     4               /* Set for any type of private room */
-#define QR_PASSWORDED  8               /* Set if there's a password too    */
-#define QR_GUESSNAME   16              /* Set if it's a guessname room     */
-#define QR_DIRECTORY   32              /* Directory room                   */
-#define QR_UPLOAD      64              /* Allowed to upload                */
-#define QR_DOWNLOAD    128             /* Allowed to download              */
-#define QR_VISDIR      256             /* Visible directory                */
-#define QR_ANONONLY    512             /* Anonymous-Only room              */
-#define QR_ANON2       1024            /* Anonymous-Option room            */
-#define QR_NETWORK     2048            /* Shared network room              */
-#define QR_PREFONLY    4096            /* Preferred status needed to enter */
-#define QR_READONLY    8192            /* Aide status required to post     */
-
- Then it returns another '|' symbol, followed by a second set of bits comprised
-of the following:
-
-#define QR2_SYSTEM     1               /* System room; hide by default     */
-#define QR2_SELFLIST   2               /* Self-service mailing list mgmt   */
-
- Other bits may be defined in the future.  The listing terminates, as with
-all listings, with "000" on a line by itself.
-
- Starting with version 4.01 and above, floors are supported.  The first
-argument to LKRN should be the number of the floor to list rooms from.  Only
-rooms from this floor will be listed.  If no arguments are passed to LKRN, or
-if the floor number requested is (-1), rooms on all floors will be listed.
-
- The third field displayed on each line is the number of the floor the room
-is on.  The LFLR command should be used to associate floor numbers with
-floor names.
-
- The fourth field displayed on each line is a "room listing order."  Unless
-there is a compelling reason not to, clients should sort any received room
-listings by this value.
- The fifth field is a special bit bucket containing fields which pertain to
-room access controls:
-
-#define UA_KNOWN                2      /* Known room */
-#define UA_GOTOALLOWED          4      /* Access will be granted to this room
-                                        * if the user calls it up by name */
-#define UA_HASNEWMSGS           8      /* Unread messages exist in room */
-#define UA_ZAPPED              16      /* Zapped from known rooms list */
- LKRO   (List Known Rooms with Old [no new] messages)
-
- This follows the same usage and format as LKRN.
-
-
- LZRM   (List Zapped RooMs)
-
- This follows the same usage and format as LKRN and LKRO.
-
-
- LKRA   (List All Known Rooms)
-
- Same format.  Lists all known rooms, with or without new messages.
-
-
- LRMS   (List all accessible RooMS)
-
- Again, same format.  This command lists all accessible rooms, known and
-forgotten, with and without new messages.  It does not, however, list
-inaccessible private rooms.
-
-
- LPRM   (List all Public RooMs)
-
- Again, same format.  This command lists all public rooms, and nothing else.
-Unlike the other list rooms commands, this one can be executed without logging
-in.
-
-
- GETU   (GET User configuration)
-
- This command retrieves the screen dimensions and user options for the
-currently logged in account.  ERROR + NOT_LOGGED_IN will be returned if no
-user is logged in, of course.  Otherwise, OK will be returned, followed by
-four parameters.  The first parameter is the user's screen width, the second
-parameter is the user's screen height, and the third parameter is a bag of
-bits with the following meanings:
-
- #define US_LASTOLD    16              /* Print last old message with new  */
- #define US_EXPERT     32              /* Experienced user                 */
- #define US_UNLISTED   64              /* Unlisted userlog entry           */
- #define US_NOPROMPT   128             /* Don't prompt after each message  */
- #define US_DISAPPEAR  512             /* Use "disappearing msg prompts"   */
- #define US_PAGINATOR  2048            /* Pause after each screen of text  */
-
- There are other bits, too, but they can't be changed by the user (see below).
-
-
- SETU   (SET User configuration)
-
- This command does the opposite of SETU: it takes the screen dimensions and
-user options (which were probably obtained with a GETU command, and perhaps
-modified by the user) and writes them to the user account.  This command
-should be passed three parameters: the screen width, the screen height, and
-the option bits (see above).  It returns ERROR + NOT_LOGGED_IN if no user is
-logged in, and ERROR + ILLEGAL_VALUE if the parameters are incorrect.
-
- Note that there exist bits here which are not listed in this document.  Some
-are flags that can only be set by Aides or the system administrator.  SETU
-will ignore attempts to toggle these bits.  There also may be more user
-settable bits added at a later date.  To maintain later downward compatibility,
-the following procedure is suggested:
-
- 1. Execute GETU to read the current flags
- 2. Toggle the bits that we know we can toggle
- 3. Execute SETU to write the flags
-
- If we are passed a bit whose meaning we don't know, it's best to leave it
-alone, and pass it right back to the server.  That way we can use an old
-client on a server that uses an unknown bit without accidentally clearing
-it every time we set the user's configuration.
-
-
- GOTO   (GOTO a 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 two additional reserved room names:
- "_MAIL_" translates to the system's designated room for e-mail messages.
- "_BITBUCKET_" goes to whatever room has been chosen for messages
-without a home.
-
- 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:
-
- 1. Execute a GOTO command without supplying any password.
- 2. ERROR + PASSWORD_REQUIRED will be returned.  The client now knows that
-the room is passworded, and prompts the user for a password.
- 3. Execute a GOTO command, supplying both the room name and the password.
- 4. 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
- 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.
-
-
- MSGS   (get pointers to MeSsaGeS in this room)
-
- 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, or "first" plus a
-number, for the corresponding effect.  If no parameters are specified, "all"
-is assumed.
-
- In Citadel 5.00 and above, the client may also specify "gt" plus a number,
-to list all messages in the current room with a message number greater than
-the one specified.
-
- The third argument, valid only in Citadel 5.60 and above, 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.
-
- 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.
-
-
- MSG0   (read MeSsaGe, mode 0)
-
- 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
- 1 = Headers only
- 2 = Body only
- 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.  The currently defined types are:
-  0 = "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 = 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 = MIME format message.  The message text is expected to contain a header
-with the "Content-type:" directive (and possibly others).
-
- 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=   Information 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.
-
-
- WHOK   (WHO Knows room)
-
- This command is available only to Aides.  ERROR + HIGHER_ACCESS_REQUIRED 
-will be returned if the user is not an Aide.  Otherwise, it returns
-LISTING_FOLLOWS and then lists, one user per line, every user who has
-access to the current room.
-
-
- INFO   (get server INFO)
-
- This command will *always* return LISTING_FOLLOWS and then print out a
-listing of zero or more strings.  Client software should be written to expect
-anywhere from a null listing to an infinite number of lines, to allow later
-backward compatibility.  The current implementation defines the following
-parts of the listing:
-
- Line 1  - Your unique session ID on the server
- Line 2  - The node name of the server BBS
- Line 3  - Human-readable node name of the server BBS
- Line 4  - The fully-qualified domain name (FQDN) of the server
- Line 5  - The name of the server software, i.e. "Citadel 4.00"
- Line 6  - (The revision level of the server code) * 100
- Line 7  - The geographical location of the BBS (city and state if in the US)
- Line 8  - The name of the system administrator
- Line 9  - A number identifying the server type (see below)
- Line 10 - The text of the system's paginator prompt
- Line 11 - Floor Flag.  1 if the system supports floors, 0 otherwise.
- Line 12 - Paging level.  0 if the system only supports inline paging,
-           1 if the system supports "extended" paging (check-only and
-           multiline modes).  See the SEXP command for further information.
- Line 13 - The "nonce" for this session, for support of APOP-style
-           authentication.  If this field is present, clients may authenticate
-           in this manner.
- Line 14 - Set to nonzero if this server supports the QNOP command.
- Line 15 - Set to nonzero if this server is capable of connecting to a
-           directory service using LDAP.
-
- *** NOTE! ***   The "server type" code is intended to promote global
-compatibility in a scenario in which developers have added proprietary
-features to their servers or clients.  We are attempting to avoid a future
-situation in which users need to keep different client software around for
-each BBS they use.  *Please*, if you are a developer and plan to add
-proprietary features:
-
- -> Your client programs should still be able to utilize servers other than
-your own.
- -> Clients other than your own should still be able to utilize your server,
-even if your proprietary extensions aren't supported.
- -> Please contact Art Cancro <ajc@uncensored.citadel.org> and obtain a unique
-server type code, which can be assigned to your server program.
- -> If you document what you did in detail, perhaps it can be added to a
-future release of the Citadel program, so everyone can enjoy it.  Better
-yet, just work with the Citadel development team on the main source tree.
-
- If everyone follows this scheme, we can avoid a chaotic situation with lots
-of confusion about which client program works with which server, etc.  Client
-software can simply check the server type (and perhaps the revision level)
-to determine ahead of time what commands may be utilized.
-
- Please refer to "developers.txt" for information on what codes belong to whom.
-
-
-
- RDIR   (Read room DIRectory)
-
- Use this command to read the directory of a directory room.  ERROR + NOT_HERE
-will be returned if the room has no directory, ERROR + HIGHER_ACCESS_REQUIRED
-will be returned if the room's directory is not visible and the user does not
-have Aide or Room Aide privileges, ERROR + NOT_LOGGED_IN will be returned if
-the user is not logged in; otherwise LISTING_FOLLOWS will be returned,
-followed by the room's directory.  Each line of the directory listing will
-contain three fields: a filename, the length of the file, and a description.
-
- The server message contained on the same line with LISTING_FOLLOWS will
-contain the name of the system and the name of the directory, such as:
-
-  uncensored.citadel.org|/usr/bbs/files/my_room_directory
-
-
- SLRP   (Set Last-message-Read Pointer)
-
- This command marks all messages in the current room as read (seen) up to and
-including the specified number.  Its sole parameter is the number of the last
-message that has been read.  This allows the pointer to be set at any
-arbitrary point in the room.  Optionally, the parameter "highest" may be used
-instead of a message number, to set the pointer to the number of the highest
-message in the room, effectively marking all messages in the room as having
-been read (ala the Citadel <G>oto command).
-
- The command will return OK if the pointer was set, or ERROR + NOT_LOGGED_IN
-if the user is not logged in.  If OK is returned, it will be followed by a
-single argument containing the message number the last-read-pointer was set to.
-
-
- INVT   (INViTe a user to a room)
-
- This command may only be executed by Aides, or by the room aide for the
-current room.  It is used primarily to add users to invitation-only rooms,
-but it may also be used in other types of private rooms as well.  Its sole
-parameter is the name of the user to invite.
-
- The command will return OK if the operation succeeded.  ERROR + NO_SUCH_USER
-will be returned if the user does not exist, ERROR + HIGHER_ACCESS_REQUIRED
-will be returned if the operation would have been possible if the user had
-higher access, and ERROR + NOT_HERE may be returned if the room is not a
-private room.
-
-
- KICK   (KICK a user out of a room)
-
- This is the opposite of INVT: it is used to kick a user out of a private
-room.  It can also be used to kick a user out of a public room, but the
-effect will only be the same as if the user <Z>apped the room - a non-stupid
-user can simply un-zap the room to get back in.
-
-
- GETR   (GET Room attributes)
-
- This command is used for editing the various attributes associated with a
-room.  A typical "edit room" command would work like this:
- 1. Use the GETR command to get the current attributes
- 2. Change some of them around
- 3. Use SETR (see below) to save the changes
- 4. Possibly also change the room aide using the GETA and SETA commands
-
- GETR takes no arguments.  It will only return OK if the SETR command will
-also return OK.  This allows client software to tell the user that he/she
-can't edit the room *before* going through the trouble of actually doing the
-editing.  Possible return codes are:
-
- ERROR+NOT_LOGGED_IN          - No user is logged in.
- ERROR+HIGHER_ACCESS_REQUIRED - Not enough access.  Typically, only aides
-and the room aide associated with the current room, can access this command.
- OK                           - Command succeeded.  Parameters are returned.
-
- If OK is returned, the following parameters will be returned as well:
-
- 0. The name of the room
- 1. The room's password (if it's a passworded room)
- 2. The name of the room's directory (if it's a directory room)
- 3. Various flags (bits) associated with the room (see LKRN cmd above)
- 4. The floor number on which the room resides
- 5. The room listing order
- 6. The default view for the room (see views.txt)
- 7. A second set of flags (bits) associated with the room
-
-
- SETR   (SET Room attributes)
-
- This command sets various attributes associated with the current room.  It
-should be passed the following arguments:
-
- 0. The name of the room
- 1. The room's password (if it's a passworded room)
- 2. The name of the room's directory (if it's a directory room)
- 3. Various flags (bits) associated with the room (see LKRN cmd above)
- 4. "Bump" flag (see below)
- 5. The floor number on which the room should reside
- 6. The room listing order
- 7. The default view for the room (see views.txt)
- 8. A second set of flags (bits) associated with the room
-
- *Important: You should always use GETR to retrieve the current attributes of
-the room, then change what you want to change, and then use SETR to write it
-all back.  This is particularly important with respect to the flags: if a
-particular bit is set, and you don't know what it means, LEAVE IT ALONE and
-only toggle the bits you want to toggle.  This will allow for upward
-compatibility.
-
- The _BASEROOM_, user's Mail> and Aide> rooms can only be partially edited.
-Any changes which cannot be made will be silently ignored.
-
- If the room is a private room, you have the option of causing all users who
-currently have access, to forget the room.  If you want to do this, set the
-"bump" flag to 1, otherwise set it to 0.
-
-
- GETA
-
- This command is used to get the name of the Room Aide for the current room.
-It will return ERROR + NOT_LOGGED_IN if no user is logged in, or OK if the
-command succeeded.  Along with OK there will be returned one parameter: the
-name of the Room Aide.  A conforming server must guarantee that the user is
-always in some room.
-
-
- SETA
-
- The opposite of GETA, used to set the Room Aide for the current room.  One
-parameter should be passed, which is the name of the user who is to be the
-new Room Aide.  Under Citadel, this command may only be executed by Aides
-and by the *current* Room Aide for the room.  Return codes possible are:
- ERROR + NOT_LOGGED_IN          (Not logged in.)
- ERROR + HIGHER_ACCESS_REQUIRED (Higher access required.)
- ERROR + NOT_HERE               (Room cannot be edited.)
- OK                             (Command succeeded.)
-
-
- ENT0   (ENTer message, mode 0)
-
- This command is used to enter messages into the system.  It accepts four
-arguments:
-
-  0  -  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.  If it is set to 2, the
-server will accept an "apparent" post name if the user is privileged enough.
-This post name is arg 5.
-  1  -  Recipient.  This argument is utilized only for private mail messages.
-It is ignored for public messages.  It contains, of course, the name of the
-recipient of the message.
-  2  -  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.  Any valid Citadel format type may be used (this will
-typically be 0; see the MSG0 command above).
-  4  -  Subject.  If present, this argument will be used as the subject of
-the message.
-  5  -  Post name.  When postflag is 2, this is the name you are posting as.
-This is an Aide only command.
-
- 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.
-  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).
-  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.
-
-
- RINF   (read Room INFormation file)
-
- Each room has associated with it a text file containing a description of
-the room, perhaps containing its intended purpose or other important
-information.  The info file for the Lobby> (the system's base room) is
-often used as a repository for system bulletins and the like.
-
- This command, which accepts no arguments, is simply used to read the info
-file for the current room.  It will return LISTING_FOLLOWS followed by
-the text of the message (always in format type 0) if the request can be
-honored, or ERROR if no info file exists for the current room (which is
-often the case).  Other error description codes may accompany this result.
-
- When should this command be used?  This is, of course, up to the discretion
-of client software authors, but in Citadel it is executed in two situations:
-the first time the user ever enters a room; and whenever the contents of the
-file change.  The latter can be determined from the result of a GOTO command,
-which will tell the client whether the file needs to be read (see GOTO above).
-
-
- DELE   (DELEte a message)
-
- Delete a message from the current room.  The one argument that should be
-passed to this command is the message number of the message to be deleted.
-The return value will be OK if the message was deleted, or an ERROR code.
-If the delete is successful, the message's reference count is decremented, and
-if the reference count reaches zero, the message is removed from the message
-base.
-
-
- MOVE   (MOVE or copy a message to a different room)
-
- Move or copy a message to a different room.  This command expects to be
-passed three arguments:
- 0: the message number 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.
-
-
- KILL   (KILL current room)
-
- This command deletes the current room.  It accepts a single argument, which
-should be nonzero to actually delete the room, or zero to merely check
-whether the room can be deleted.
-
- Once the room is deleted, the current room is undefined.  It is suggested
-that client software immediately GOTO another room (usually _BASEROOM_)
-after this command completes.
-
- Possible return codes:
-
- OK  -  room has been deleted (or, if checking only, request is valid).
- ERROR+NOT_LOGGED_IN  -  no user is logged in.
- ERROR+HIGHER_ACCESS_REQUIRED  -  not enough access to delete rooms.
- ERROR+NOT_HERE  -  this room can not be deleted.
-
-
- CRE8   (CRE[ate] a new room)
-
- This command is used to create a new room.  Like some of the other
-commands, it provides a mechanism to first check to see if a room can be
-created before actually executing the command.  CRE8 accepts the following
-arguments:
-
- 0  -  Create flag.  Set this to 1 to actually create the room.  If it is
-set to 0, the server merely checks that there is a free slot in which to
-create a new room, and that the user has enough access to create a room.  It
-returns OK if the client should go ahead and prompt the user for more info,
-or ERROR or ERROR+HIGHER_ACCESS_REQUIRED if the command will not succeed.
- 1  -  Name for new room.
- 2  -  Access type for new room:
-       0  -  Public
-       1  -  Private; can be entered by guessing the room's name
-       2  -  Private; can be entered by knowing the name *and* password
-       3  -  Private; invitation only (sometimes called "exclusive")
-       4  -  Personal (mailbox for this user only)
- 3  -  Password for new room (if it is a type 2 room)
- 4  -  Floor number on which the room should reside (optional)
- 5  -  Set to 1 to avoid automatically gaining access to the created room.
- 6  -  The default "view" for the room.
-
- If the create flag is set to 1, the room is created (unless something
-went wrong and an ERROR return is sent), and the server returns OK, but
-the session is **not** automatically sent to that room.  The client still
-must perform a GOTO command to go to the new room.
-
-
- FORG   (FORGet the current room)
-
- This command is used to forget (zap) the current room.  For those not
-familiar with Citadel, this terminology refers to removing the room from
-a user's own known rooms list, *not* removing the room itself.  After a
-room is forgotten, it no longer shows up in the user's known room list,
-but it will exist in the user's forgotten room list, and will return to the
-known room list if the user goes to the room (in Citadel, this is
-accomplished by explicitly typing the room's name in a <.G>oto command).
-
- The command takes no arguments.  If the command cannot execute for any
-reason, ERROR will be returned.  ERROR+NOT_LOGGED_IN or ERROR+NOT_HERE may
-be returned as they apply.
-
- If the command succeeds, OK will be returned.  At this point, the current
-room is **undefined**, and the client software is responsible for taking
-the user to another room before executing any other room commands (usually
-this will be _BASEROOM_ since it is always there).
-
-
- MESG    (read system MESsaGe)
-
- This command is used to display system messages and/or help files.  The
-single argument it accepts is the name of the file to display.  IT IS CASE
-SENSITIVE.  Citadel looks for these files first in the "messages"
-subdirectory and then in the "help" subdirectory.
-
- If the file is found, LISTING_FOLLOWS is returned, followed by a pathname
-to the file being displayed.  Then the message is printed, in format type 0
-(see MSG0 command for more information on this).  If the file is not found,
-ERROR is returned.
-
- There are some "well known" names of system messages which client software
-may expect most servers to carry:
-
- hello        -  Welcome message, to be displayed before the user logs in.
- changepw     -  To be displayed whenever the user is prompted for a new
-                 password.  Warns about picking guessable passwords and such.
- register     -  Should be displayed prior to the user entering registration.
-                 Warnings about not getting access if not registered, etc.
- help         -  Main system help file.
- goodbye      -  System logoff banner; display when user logs off.
- roomaccess   -  Information about how public rooms and different types of
-                 private rooms function with regards to access.
- unlisted     -  Tells users not to choose to be unlisted unless they're
-                 really paranoid, and warns that aides can still see
-                 unlisted userlog entries.
-
- Citadel provides these for the Citadel Unix text client.  They are
-probably not very useful for other clients:
-
- mainmenu     -  Main menu (when in idiot mode).
- aideopt      -  .A?
- readopt      -  .R?
- entopt       -  .E?
- dotopt       -  .?
- saveopt      -  Options to save a message, abort, etc.
- entermsg     -  Displayed just before a message is entered, when in
-                 idiot mode.
-
-
- GNUR   (Get Next Unvalidated User)
-
- This command shows the name of a user that needs to be validated.  If there
-are no unvalidated users, OK is returned.  Otherwise, MORE_DATA is returned
-along with the name of the first unvalidated user the server finds.  All of
-the usual ERROR codes may be returned as well (for example, if the user is
-not an Aide and cannot validate users).
-
- A typical "Validate New Users" command would keep executing this command,
-and then validating each user it returns, until it returns OK when all new
-users have been validated.
-
-
- GREG   (Get REGistration for user)
-
- This command retrieves the registration info for a user, whose name is the
-command's sole argument.  All the usual error messages can be returned.  If
-the command succeeds, LISTING_FOLLOWS is returned, followed by the user's name
-(retrieved from the userlog, with the right upper and lower case etc.)  The
-contents of the listing contains one field per line, followed by the usual
-000 on the last line.
-
- The following lines are defined.  Others WILL be added in the futre, so all
-software should be written to read the lines it knows about and then ignore
-all remaining lines:
-
- Line 1:  User number
- Line 2:  Password
- Line 3:  Real name
- Line 4:  Street address or PO Box
- Line 5:  City/town/village/etc.
- Line 6:  State/province/etc.
- Line 7:  ZIP Code
- Line 8:  Telephone number
- Line 9:  Access level
- Line 10: Internet e-mail address
- Line 11: Country
-
- Users without Aide privileges may retrieve their own registration using
-this command.  This can be accomplished either by passing the user's own
-name as the argument, or the string "_SELF_".  The command will always
-succeed when used in this manner, unless no user is logged in.
-
-
- VALI   (VALIdate user)
-
- This command is used to validate users.  Obviously, it can only be executed
-by users with Aide level access.  It should be passed two parameters: the
-name of the user to validate, and the desired access level
-
- If the command succeeds, OK is returned.  The user's access level is changed
-and the "need validation" bit is cleared.  If the command fails for any
-reason, ERROR, ERROR+NO_SUCH_USER, or ERROR+HIGHER_ACCESS_REQUIRED will be
-returned.
-
-
- EINF   (Enter INFo file for room)
-
- Transmit the info file for the current room with this command.  EINF uses
-a boolean flag (1 or 0 as the first and only argument to the command) to
-determine whether the client actually wishes to transmit a new info file, or
-is merely checking to see if it has permission to do so.
-
- If the command cannot succeed, it returns ERROR.
- If the client is only checking for permission, and permission will be
-granted, OK is returned.
- If the client wishes to transmit the new info file, SEND_LISTING is
-returned, and the client should transmit the text of the info file, ended
-by the usual 000 on a line by itself.
-
-
- LIST   (user LISTing)
-
- This is a simple user listing.  It always succeeds, returning
-LISTING_FOLLOWS followed by zero or more user records, 000 terminated.  The
-fields on each line are as follows:
-
- 1. User name
- 2. Access level
- 3. User number
- 4. Date/time of last login (Unix format)
- 5. Times called
- 6. Messages posted
- 7. Password (listed only if the user requesting the list is an Aide)
-
- Unlisted entries will also be listed to Aides logged into the server, but
-not to ordinary users.
-
-
- REGI   (send REGIstration)
-
- Clients will use this command to transmit a user's registration info.  If
-no user is logged in, ERROR+NOT_LOGGED_IN is returned.  Otherwise,
-SEND_LISTING is returned, and the server will expect the following information
-(terminated by 000 on a line by itself):
-
- Line 1:  Real name
- Line 2:  Street address or PO Box
- Line 3:  City/town/village/etc.
- Line 4:  State/province/etc.
- Line 5:  ZIP Code
- Line 6:  Telephone number
- Line 7:  e-mail address
- Line 8:  Country
-
-
- CHEK   (CHEcK various things)
-
- When logging in, there are various things that need to be checked.   This
-command will return ERROR+NOT_LOGGED_IN if no user is logged in.  Otherwise
-it returns OK and the following parameters:
-
- 0: Number of new private messages in Mail>
- 1: Nonzero if the user needs to register
- 2: (Relevant to Aides only) Nonzero if new users require validation
- 3: The user's preferred Internet e-mail address
-
-
- DELF   (DELete a File)
-
- This command deletes a file from the room's directory, if there is one.  The
-name of the file to delete is the only parameter to be supplied.  Wildcards
-are not acceptable, and any slashes in the filename will be converted to
-underscores, to prevent unauthorized access to neighboring directories.  The
-possible return codes are:
-
- OK                            -  Command succeeded.  The file was deleted.
- ERROR+NOT_LOGGED_IN           -  Not logged in.
- ERROR+HIGHER_ACCESS_REQUIRED  -  Not an Aide or Room Aide.
- ERROR+NOT_HERE                -  There is no directory in this room.
- ERROR+FILE_NOT_FOUND          -  Requested file was not found.
-
-
- MOVF   (MOVe a File)
-
- This command is similar to DELF, except that it moves a file (and its
-associated file description) to another room.  It should be passed two
-parameters: the name of the file to move, and the name of the room to move
-the file to.  All of the same return codes as DELF may be returned, and also
-one additional one: ERROR+NO_SUCH_ROOM, which means that the target room
-does not exist.  ERROR+NOT_HERE could also mean that the target room does
-not have a directory.
-
-
- NETF   (NETwork send a File)
-
- This command is similar to MOVF, except that it attempts to send a file over
-the network to another system.  It should be passed two parameters: the name
-of the file to send, and the node name of the system to send it to.  All of
-the same return codes as MOVF may be returned, except for ERROR+NO_SUCH_ROOM.
-Instead, ERROR+NO_SUCH_SYSTEM may be returned if the name of the target
-system is invalid.
-
- The name of the originating room will be sent along with the file.  Most
-implementations will look for a room with the same name at the receiving end
-and attempt to place the file there, otherwise it goes into a bit bucket room
-for miscellaneous files.  This is, however, beyond the scope of this document;
-see elsewhere for more details.
-
-
- RWHO   (Read WHO's online)
-
- Displays a list of all users connected to the server.  No error codes are
-ever returned.  LISTING_FOLLOWS will be returned, followed by zero or more
-lines containing the following three fields:
-
- 0 - Session ID.  Citadel fills this with the pid of a server program.
- 1 - User name.
- 2 - The name of the room the user is currently in.  This field might not
-be displayed (for example, if the user is in a private room) or it might
-contain other information (such as the name of a file the user is
-downloading).
- 3 - (server v4.03 and above) The name of the host the client is connecting
-from, or "localhost" if the client is local.
- 4 - (server v4.04 and above) Description of the client software being used
- 5 - The last time, locally to the server, that a command was received from
-     this client (Note: NOOP's don't count)
- 6 - The last command received from a client. (NOOP's don't count)
- 7 - Session flags.  These are: + (spoofed address), - (STEALTH mode), *
-     (posting) and . (idle).
- 8 - Actual user name, if user name is masqueraded and viewer is an Aide.
- 9 - Actual room name, if room name is masqueraded and viewer is an Aide.
- 10 - Actual host name, if host name is masqueraded and viewer is an Aide.
- 11 - Nonzero if the session is a logged-in user, zero otherwise.
-
- The listing is terminated, as always, with the string "000" on a line by
-itself.
-
-
- OPEN   (OPEN a file for download)
-
- This command is used to open a file for downloading.  Only one download
-file may be open at a time.  The only argument to this command is the name
-of the file to be opened.  The user should already be in the room where the
-file resides.  Possible return codes are:
-
- ERROR+NOT_LOGGED_IN
- ERROR+NOT_HERE                (no directory in this room)
- ERROR+FILE_NOT_FOUND          (could not open the file)
- ERROR                         (misc errors)
- OK                            (file is open)
-
- If the file is successfully opened, OK will be returned, along with the
-size (in bytes) of the file, the time of last modification (if applicable),
-the filename (if known), and the MIME type of the file (if known).
-
-
- CLOS   (CLOSe the download file)
-
- This command is used to close the download file.  It returns OK if the
-file was successfully closed, or ERROR if there wasn't any file open in the
-first place.
-
-
- READ   (READ from the download file)
-
- Two arguments are passed to this command.  The first is the starting position
-in the download file, and the second is the total number of bytes to be
-read.  If the operation can be performed, BINARY_FOLLOWS will be returned,
-along with the number of bytes to follow.  Then, immediately following the
-newline, will be that many bytes of binary data.  The client *must* read
-exactly that number of bytes, otherwise the client and server will get out
-of sync.
-
- If the operation cannot be performed, any of the usual error codes will be
-returned.
-
-
- UOPN   (OPeN a file for Uploading)
-
- This command is similar to OPEN, except that this one is used when the
-client wishes to upload a file to the server.  The first argument is the name
-of the file to create, and the second argument is a one-line comment
-describing the contents of the file.  Only one upload file may be open at a
-time.  Possible return codes are:
-
- ERROR+NOT_LOGGED_IN
- ERROR+NOT_HERE               (no directory in this room)
- ERROR+FILE_NOT_FOUND         (a name must be specified)
- ERROR                        (miscellaneous errors)
- ERROR+ALREADY_EXISTS         (a file with the same name already exists)
- OK
-
- If OK is returned, the command has succeeded and writes may be performed.
-
-
- UCLS   (CLoSe the Upload file)
-
- Close the file opened with UOPN.  An argument of "1" should be passed to
-this command to close and save the file; otherwise, the transfer will be
-considered aborted and the file will be deleted.  This command returns OK
-if the operation succeeded or ERROR if it did not.
-
-
- WRIT   (WRITe to the upload file)
-
- If an upload file is open, this command may be used to write to it.  The
-argument passed to this command is the number of bytes the client wishes to
-transmit.  An ERROR code will be returned if the operation cannot be
-performed.
-
- If the operation can be performed, SEND_BINARY will be returned, followed
-by the number of bytes the server is expecting.  The client must then transmit
-exactly that number of bytes.  Note that in the current implementation, the
-number of bytes the server is expecting will always be the number of bytes
-the client requested to transmit, but the client software should never assume
-that this will always happen, in case changes are made later.
-
-
- QUSR   (Query for a USeR)
-
- This command is used to check to see if a particular user exists.  The only
-argument to this command is the name of the user being searched for.  If
-the user exists, OK is returned, along with the name of the user in the userlog
-(so the client software can learn the correct upper/lower casing of the name
-if necessary).  If the user does not exist, ERROR+NO_SUCH_USER is returned.
-No login or current room is required to utilize this command.
-
-
- OIMG   (Open an IMaGe file)
-
- Open an image (graphics) file for downloading.  Once opened, the file can be
-read as if it were a download file.  This implies that an image and a download
-cannot be opened at the same time.  OIMG returns the same result codes as OPEN.
-
- All images will be in GIF (Graphics Interchange Format).  In the case of
-Citadel, the server will convert the supplied filename to all lower case,
-append the characters ".gif" to the filename, and look for it in the "images"
-subdirectory.  As with the MESG command, there are several "well known"
-images which are likely to exist on most servers:
-
- hello        - "Welcome" graphics to be displayed alongside MESG "hello"
- goodbye      - Logoff banner graphics to be displayed alongside MESG "goodbye"
- background   - Background image (usually tiled) for graphical clients
-
- The following "special" image names are defined in Citadel server version
-5.00 and above:
-
- _userpic_    - Picture of a user (send the username as the second argument)
- _floorpic_   - A graphical floor label (send the floor number as the second
-                argument).  Clients which request a floor picture will display
-                the picture *instead* of the floor name.
- _roompic_    - A graphic associated with the *current* room.  Clients which
-                request a room picture will display the picture in *addition*
-                to the room name (i.e. it's used for a room banner, as
-                opposed to the floor picture's use in a floor listing).
-
-
- NETP   (authenticate as network session with connection NET Password)
-
- This command is used by client software to identify itself as a transport
-session for IGnet/Open BBS to BBS networking.  It should be called with
-two arguments: the node name of the calling system, and the "shared secret"
-password for that connection.  If the authentication succeeds, NETP will
-return OK, otherwise, it returns ERROR.
-
- NSYN   (Network SYNchronize room)
- This command can be used to synchronize the contents of a room on the
-network.  It is only usable by Aides.  It accepts one argument: the name of
-a network node (which must be a valid one).
- When NSYN is run, the *entire* contents of the current room will be spooled
-to the specified node, without regard to whether any of the messages have
-already undergone network processing.  It is up to the receiving node to
-check for duplicates (the Citadel networker does handle this) and avoid
-posting them twice.
- The command returns OK upon success or ERROR if the user is not an Aide.
-  
- NUOP   (Network Upload OPen file)
-
- Open a network spool file for uploading.  The client must have already
-identified itself as a network session using the NETP command.  If the command
-returns OK, the client may begin transmitting IGnet/Open spool data using
-a series of WRIT commands.  When a UCLS command is issued, the spooled data
-is entered into the BBS if the argument to UCLS is 1 or discarded if the
-argument to UCLS is 0.  If the client has not authenticated itself with a
-NETP command, ERROR+HIGHER_ACCESS_REQUIRED will be returned.
-
-
- NDOP   (Network Download OPen file)
-
- Open a network spool file for downloading.  The client must have already
-identified itself as a network session using the NETP command.  If the command
-returns OK, the client may begin receiving IGnet/Open spool data using
-a series of READ commands.  When a CLOS command is issued, the spooled data
-is deleted from the server and may not be read again.  If the client has not
-authenticated itself with a NETP command, ERROR+HIGHER_ACCESS_REQUIRED will
-be returned.
-
-
- LFLR   (List all known FLooRs)
-
- On systems supporting floors, this command lists all known floors.  The
-command accepts no parameters.  It will return ERROR+NOT_LOGGED_IN if no
-user is logged in.  Otherwise it returns LISTING_FOLLOWS and a list of
-the available floors, each line consisting of three fields:
-
- 1. The floor number associated with the floor
- 2. The name of the floor
- 3. Reference count (number of rooms on this floor)
-
-
- CFLR   (Create a new FLooR)
-
- This command is used to create a new floor.  It should be passed two
-arguments: the name of the new floor to be created, and a 1 or 0 depending
-on whether the client is actually creating a floor or merely checking to
-see if it has permission to create the floor.   The user must be logged in
-and have Aide privileges to create a floor.
-
- If the command succeeds, it will return OK followed by the floor number
-associated with the new floor.  Otherwise, it will return ERROR (plus perhaps
-HIGHER_ACCESS_REQUIRED, ALREADY_EXISTS, or INVALID_FLOOR_OPERATION)
-followed by a description of why the command failed.
-
-
- KFLR   (Kill a FLooR)
-
- This command is used to delete a floor.  It should be passed two
-argument: the *number* of the floor to be deleted, and a 1 or 0 depending
-on whether the client is actually deleting the floor or merely checking to
-see if it has permission to delete the floor.  The user must be logged in
-and have Aide privileges to delete a floor.
-
- Floors that contain rooms may not be deleted.  If there are rooms on a floor,
-they must be either deleted or moved to different floors first.  This implies
-that the Main Floor (floor 0) can never be deleted, since Lobby>, Mail>, and
-Aide> all reside on the Main Floor and cannot be deleted.
-
- If the command succeeds, it will return OK.  Otherwise it will return
-ERROR (plus perhaps HIGHER_ACCESS_REQUIRED or INVALID_FLOOR_OPERATION)
-followed by a description of why the command failed.
-
-
- EFLR   (Edit a FLooR)
-
- Edit the parameters of a floor.  The client may pass one or more parameters
-to this command:
-
- 1. The number of the floor to be edited
- 2. The desired new name
-
- More parameters may be added in the future.  Any parameters not passed to
-the server will remain unchanged.  A minimal command would be EFLR and a
-floor number -- which would do nothing.  EFLR plus the floor number plus a
-floor name would change the floor's name.
-
- If the command succeeds, it will return OK.  Otherwise it will return
-ERROR (plus perhaps HIGHER_ACCESS_REQUIRED or INVALID_FLOOR_OPERATION)
-
-
-IDEN (IDENtify the client software)
-
- The client software has the option to identify itself to the server.
-Currently, the server does nothing with this information except to write
-it to the syslog to satisfy the system administrator's curiosity.  Other
-uses might become apparent in the future.
-
- The IDEN command should contain five fields: a developer ID number (same as
-the server developer ID numbers in the INFO command -- please obtain one if
-you are a new developer), a client ID number (which does not have to be
-globally unique - only unique within the domain of the developer number),
-a version number, a free-form text string describing the client, and the name
-of the host the user is located at.
-
- It is up to the server to determine whether to accept the host name or to
-use the host name it has detected itself.  Generally, if the client is
-running on a trusted host (either localhost or a well-known publically
-accessible client) it should use the host name transmitted by IDEN,
-otherwise it should use the host name it has detected itself.
-
- IDEN always returns OK, but since that's the only way it ever returns
-there's no point in checking the result code.
-
-
-IPGM (identify as an Internal ProGraM)
-
- IPGM is a low-level command that should not be used by normal user clients.
-It is used for various utilities to communicate with the server on the same
-host.  For example, the "sendcommand" utility logs onto the server as an
-internal program in order to run arbitrary server commands.  Since user clients
-do not utilize this command (or any of its companion commands), developers
-writing Citadel-compatible servers need not implement it.
-
- The sole argument to IPGM is the system's internal program password.  This
-password is generated by the setup program and stored in the config file.
-Since internal programs have access to the config file, they know the correct
-password to use.
-
- IPGM returns OK for a correct authentication or ERROR otherwise.
-
-
-CHAT (enter CHAT mode)
-
- This command functions differently from every other command in the system.  It
-is used to implement multi-user chat.  For this to function, a new transfer
-mode, called START_CHAT_MODE, is implemented.  If a client does not support
-chat mode, it should never send a CHAT command!
-
- In chat mode, messages may arrive asynchronously from the server at any
-time.  The client may send messages at any time.  This allows the arrival of
-messages without the client having to poll for them.  Arriving messages will
-be of the form  "user|message", where the "user" portion is, of course, the
-name of the user sending the message, and "message" is the message text.
-
- Chat mode ends when the server says it ends.  The server will signal the end
-of chat mode by transmitting "000" on a line by itself.  When the client reads
-this line, it must immediately exit from chat mode without sending any
-further traffic to the server.  The next transmission sent to the server
-will be a regular server command.
-
- The Citadel server understands the following commands:
- /quit   -   Exit from chat mode (causes the server to do an 000 end)
- /who    -   List users currently in chat
- /whobbs -   List users currently in chat and on the bbs
- /me     -   Do an irc-style action.
- /join   -   Join a new "room" in which all messages are only heard by
-             people in that room.
- /msg    -   /msg <user> <msg> will send the msg to <user> only.
- /help   -   Print help information
- NOOP    -   Do nothing (silently)
-
- Any other non-empty string is treated as message text and will be broadcast
-to other users currently in chat.
-
-
- SEXP   (Send instant message)
-
- This is one of two commands which implement instant messages (also known
-as "paging").  Commands ending in "...EXP" are so-named because we called
-them "express messages" before the industry standardized on the term
-"instant messages."  When an instant message is sent, it will be
-logged in user to another.  When an instant message is sent, it will be
-displayed the next time the target user executes a PEXP or GEXP command.
-
- The SEXP command accepts two arguments: the name of the user to send the
-message to, and the text of the message.  If the message is successfully
-transmitted, OK is returned.  If the target user is not logged in or if
-anything else goes wrong, ERROR is returned.
-
- If the server supports extended paging, sending a zero-length message
-merely checks for the presence of the requested user without actually sending
-a message.  Sending a message consisting solely of a "-" (hyphen) will cause
-the server to return SEND_LISTING if the requested user is logged in, and the
-client can then transmit a multi-line page.
-
- The reserved name "broadcast" may be used instead of a user name, to
-broadcast an instant message to all users currently connected to the server.
-
- Do be aware that if an instant message is transmitted to a user who is logged
-in using a client that does not check for instant messages, the message will
-never be received.  Also, instant messages are NOT sent via the following
-transports:  SMTP, POP3.
-
-
- PEXP   (Print instant messages)   ***DEPRECATED***
-
- This command is deprecated; it will eventually disappear from the protocol and
-its use is not recommended.  Please use the GEXP command instead.
-
- Called without any arguments, PEXP simply dumps out the contents
-of any waiting instant messages.  It returns ERROR if there is a problem,
-otherwise it returns LISTING_FOLLOWS followed by all messages.
-
- So how does the client know there are instant messages waiting?  It could
-execute a random PEXP every now and then.  Or, it can check the byte in
-server return code messages, between the return code and the parameters.  In
-much the same way as FTP uses "-" to signify a continuation, Citadel uses
-an "*" in this position to signify the presence of waiting instant messages.
-
-
- EBIO   (Enter BIOgraphy)
-
- Transmit to the server a free-form text file containing a little bit of
-information about the user for other users to browse.  This is typically
-referred to as a 'bio' online.  EBIO returns SEND_LISTING if it succeeds,
-after which the client is expected to transmit the file, or any of the usual
-ERROR codes if it fails.
-
-
- RBIO   (Read BIOgraphy)
-
- Receive from the server a named user's bio.  This command should be passed
-a single argument - the name of the user whose bio is requested.  RBIO returns
-LISTING_FOLLOWS plus the bio file if the user exists and has a bio on file.
-The return has the following parameters:  the user name, user number, access
-level, date of last call, times called, and messages posted.  This command
-returns ERROR+NO_SUCH_USER if the named user does not exist.
-
- RBIO no longer considers a user with no bio on file to be an error condition.
-It now returns a message saying the user has no bio on file as the text of the
-bio.  This allows newer servers to operate with older clients.
-
-
- STEL   (enter STEaLth mode)
-
- When in "stealth mode," a user will not show up in the "Who is online"
-listing (the RWHO server command).  Only Aides may use stealth mode.  The
-STEL command accepts one argument: a 1 indicating that the user wishes to
-enter stealth mode, or a 0 indicating that the user wishes to exit stealth
-mode.  STEL returns OK if the command succeeded, ERROR+NOT_LOGGED_IN if no
-user is logged in, or ERROR+HIGHER_ACCESS_REQUIRED if the user is not an Aide;
-followed by a 1 or 0 indicating the new state.
-
- If any value other than 1 or 0 is sent by the client, the server simply
-replies with 1 or 0 to indicate the current state without changing it.
-
-The STEL command also makes it so a user does not show up in the chat room
-/who.
-
-
- LBIO   (List users who have BIOs on file)
-
- This command is self-explanatory.  Any user who has used EBIO to place a bio
-on file is listed.  LBIO almost always returns LISTING_FOLLOWS followed by
-this listing, unless it experiences an internal error in which case ERROR
-is returned.
-
-
- MSG2   (read MeSsaGe, mode 2)
-
- MSG2 follows the same calling convention as MSG0.  The difference between
-the two commands is that MSG2 outputs messages in standard RFC822 format
-rather than in Citadel proprietary format.
-
- This command was implemented in order to make various gateway programs
-easier to implement, and to provide some sort of multimedia support in the
-future.  Keep in mind that when this command is used, all messages will be
-output in fixed 80-column format.
-
-
- MSG3   (read MeSsaGe, mode 3 -- internal command)
-
- 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.
-
-
- TERM   (TERMinate another session)
-
- In a multithreaded environment, it sometimes becomes necessary to terminate
-a session that is unusable for whatever reason.  The TERM command performs
-this task.  Naturally, only Aides can execute TERM.  The command should be
-called with a single argument: the session ID (obtained from an RWHO command)
-of the session to be terminated.
-
- TERM returns OK if the session was terminated, or ERROR otherwise.  Note that
-a client program is prohibited from terminating the session it is currently
-running on.
-
- See also: REQT
-
-
- DOWN   (shut DOWN the server)
-
- This command, which may only be executed by an Aide, immediately shuts down
-the server.  It is only implemented on servers on which such an operation is
-possible, such as a multithreaded Citadel engine.  The server does not restart.
-DOWN returns OK if the user is allowed to shut down the server, in which case
-the client program should expect the connection to be immediately broken.
-
-
- SCDN   (Schedule or Cancel a shutDowN)
-
- SCDN sets or clears the "scheduled shutdown" flag.  Pass this command a 1 or
-0 to respectively set or clear the flag.  When the "scheduled shutdown" flag is
-set, the server will be shut down when there are no longer any users logged in.
-Any value other than 0 or 1 will not change the flag, only report its state.
-No users will be kicked off the system, and in fact the server is still
-available for new connections.  The command returns ERROR if it fails;
-otherwise, it returns OK followed by a number representing the current state
-of the flag.
-
-
- EMSG   (Enter a system MeSsaGe)
-
- 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.
-
-
- UIMG   (Upload an IMaGe file)
-
- UIMG is complemenary to OIMG; it is used to upload an image to the server.
-The first parameter supplied to UIMG should be 0 if the client is only checking
-for permission to upload, or 1 if the client is actually attempting to begin
-the upload operation.  The second argument is the name of the file to be
-transmitted.  In Citadel, the filename is converted to all lower case,
-appended with the characters ".gif", and stored in the "images" directory.
-
- UIMG returns OK if the client has permission to perform the requested upload,
-or ERROR+HIGHER_ACCESS_REQUIRED otherwise.  If the client requested to begin
-the operation (first parameter set to 1), an upload file is opened, and the
-client should begin writing to it with WRIT commands, then close it with a
-UCLS command.
-
- The supplied filename should be one of:
-
- ->  _userpic_   (Server will attempt to write to the user's online photo)
- ->  Any of the "well known" filenames described in the writeup for the
-     OIMG command.
-
-
- HCHG  (Hostname CHanGe)
-
- HCHG is a command, usable by any user, that allows a user to change their RWHO
-host value.  This will mask a client's originating hostname from normal
-users; access level 6 and higher can see, in an extended wholist, the actual
-hostname the user originates from.
-
- The format of an HCHG command is:
-
- HCHG <name>
-
- If a HCHG command is successful, the value OK (200) is returned.
-
-
- RCHG  (Roomname CHanGe)
-
- RCHG is a command, usable by any user, that allows a user to change their RWHO
-room value.  This will mask a client's roomname from normal users; access
-level 6 and higher can see, in an extended wholist, the actual room the user
-is in.
-
- The format of an RCHG command is:
-
- RCHG <name>
-
- If a RCHG command is successful, the value OK (200) is returned.
-
-
- UCHG  (Username CHanGe)
-
- UCHG is an aide-level command which allows an aide to effectively change their
-username.  If this value is blank, the user goes into stealth mode (see
-STEL).  Posts
-will show up as being from the real username in this mode, however.  In
-addition, the RWHO listing will include both the spoofed and real usernames.
-
- The format of an UCHG command is:
-
- UCHG <name>
-
- If a UCHG command is successful, the value OK (200) is returned.
-
-
- TIME  (get server local TIME)
-
- TIME returns OK followed by the current time measured in seconds since
-00:00:00 GMT, Jan 1, 1970 (standard Unix format).
-
- This is used in allowing a client to calculate idle times.
-
-
- AGUP   (Administrative Get User Parameters)
- ASUP   (Administrative Set User Parameters)
-
- These commands are only executable by Aides and by server extensions running
-at system-level.  They are used to get/set any and all parameters relating to
-a user account.  AGUP requires only one argument: the name of the user in
-question.  SGUP requires all of the parameters to be set.  The parameters are
-as follows, and are common to both commands:
-
- 0 - User name
- 1 - Password
- 2 - Flags (see citadel.h)
- 3 - Times called
- 4 - Messages posted
- 5 - Access level
- 6 - User number
- 7 - Timestamp of last call
- 8 - Purge time (in days) for this user (or 0 to use system default)
-
- Upon success, AGUP returns OK followed by all these parameters, and ASUP
-simply returns OK.  If the client has insufficient access to perform the
-requested operation, ERROR+HIGHER_ACCESS_REQUIRED is returned.  If the
-requested user does not exist, ERROR+NO_SUCH_USER is returned.
-
-
-
- GPEX   (Get Policy for message EXpiration)
-
- Returns the policy of the current room, floor, or site regarding the automatic
-purging (expiration) of messages.  The following policies are available:
-   0  -  Fall back to the policy of the next higher level.  If this is a room,
-         use the floor's default policy.  If this is a floor, use the system
-         default policy.  This is an invalid value for the system policy.
-   1  -  Do not purge messages automatically.
-   2  -  Purge by message count.  (Requires a value: number of messages)
-   3  -  Purge by message age.  (Requires a value: number of days)
-
- The format of this command is:  GPEX <which>
- The value of <which> must be one of: "room" "floor" "site" "mailboxes"
-
- If successful, GPEX returns OK followed by <policy>|<value>.
-
-
-
- SPEX   (Set Policy for message EXpiration)
-
- Sets the policy of the current room, floor, or site regarding the automatic
-purging (expiration) of messages.  See the writeup for the GPEX command for
-the list of available policies.
-
- The format of this command is:  SPEX <which>|<policy>|<value>
- The value of <which> must be one of: "room" "floor" "site" "mailboxes"
-
- If successful, GPEX returns OK; otherwise, an ERROR code is returned.
-
-
-
- CONF   (get or set global CONFiguration options)
-
- Retrieves or sets various system-wide configuration and policy options.  This
-command is only available to Aides.  The sole parameter accepted is a command,
-which should be either GET or SET.  If the GET command succeeds, CONF will
-return LISTING_FOLLOWS followed by the fields described below, one line at a
-time.  If the SET command succeeds, CONF will return SEND_LISTING and expect
-the fields described below, one line at a time (don't worry about other fields
-being added in the future; if a 'short' configuration list is sent, the missing
-values at the end will be left unchanged on the system).  If either command
-fails for any reason, ERROR is returned.
-
- The configuration lines are as follows:
-
- 1. Node name
- 2. Fully qualified domain name
- 3. Human-readable node name
- 4. Landline telephone number of this system
- 5. Flag (0 or 1) - creator of private room automatically becomes room aide
- 6. Server connection idle timeout (in seconds)
- 7. Initial access level for new users
- 8. Flag (0 or 1) - require registration for new users
- 9. Flag (0 or 1) - automatically move Problem User messages to twit room
- 10. Name of twit room
- 11. Text of <more> prompt
- 12. Flag (0 or 1) - restrict access to Internet mail
- 13. Geographic location of this system
- 14. Name of the system administrator
- 15. Number of maximum concurrent sessions allowed on the server
- 16. (placeholder -- this field is no longer in use)
- 17. Default purge time (in days) for users
- 18. Default purge time (in days) for rooms
- 19. Name of room to log instant messages to (or a zero-length name for none)
- 20. Access level required to create rooms
- 21. Maximum message length which may be entered into the system
- 22. Minimum number of worker threads
- 23. Maximum number of worker threads
- 24. Port number for POP3 service
- 25. Port number for SMTP service
- 26. Flag (0 or 1) - strict RFC822 adherence - don't correct From: forgeries
- 27. Flag (0 or 1) - allow Aides to zap (forget) rooms
- 28. Port number for IMAP service
- 29. How often (in seconds) to run the networker
- 30. Flag (0 or 1) - disable self-service new user registration
- 31. (placeholder -- this field is no longer in use)
- 32. Hour (0 through 23) during which database auto-purge jobs are run
- 33. Name of host where an LDAP service may be found
- 34. Port number of LDAP service on above host
- 35. LDAP Base DN
- 36. LDAP Bind DN
- 37. Password for LDAP Bind DN
- 38. Server IP address to listen on (or "0.0.0.0" for all addresses)
-
- CONF also accepts two additional commands: GETSYS and PUTSYS followed by an
-arbitrary MIME type (such as application/x-citadel-internet-config) which
-provides a means of storing generic configuration data in the Global System
-Configuration room without the need to add extra get/set commands to the
-server.
- Please note that the LDAP-specific configs have no effect on Citadel servers
-in which LDAP support is not enabled.
-
-
-
- MSG4   (read MeSsaGe, mode 4 -- output in preferred MIME format)
-
- 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.
-
-
-
- MSGP   (set MeSsaGe Preferred MIME format)
-
- 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:  MSGP text/html|text/plain
-
- The MSGP command always returns OK.
-
-
-
- OPNA   (OPeN Attachment)
-
- 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.
-
-
- GEXP   (Get instant messages)
-
- This is a more sophisticated way of retrieving instant messages than the old
-PEXP method.  If there are no instant messages waiting, PEXP returns ERROR;
-otherwise, it returns LISTING_FOLLOWS and the following arguments:
-
- 0 - a boolean value telling the client whether there are any additional
-     instant messages waiting following this one
- 1 - a Unix-style timestamp
- 2 - flags (see server.h for more info)
- 3 - the name of the sender
- 4 - the node this message originated on (for future support of PIP, ICQ, etc.)
-
- The text sent to the client will be the body of the instant message.
-
- So how does the client know there are instant messages waiting?  It could
-execute a random GEXP every now and then.  Or, it can check the byte in
-server return code messages, between the return code and the parameters.  In
-much the same way as FTP uses "-" to signify a continuation, Citadel uses
-an "*" in this position to signify the presence of waiting instant messages.
-
-
- FSCK   (check message base reference counts)
-
- Verify, via the long way, that all message referenmce counts are correct.  If
-the user has permission to do this then LISTING_FOLLOWS is returned, followed
-by a transcript of the run.  Otherwise ERROR is returned.
-
-
- DEXP   (Disable receiving instant messages)
-
- DEXP sets or clears the "disable instant messages" flag.  Pass this command a
-1 or 0 to respectively set or clear the flag.  When the "disable instant
-messages" flag is set, no one except Aides may send the user instant messages.
-Any value other than 0 or 1 will not change the flag, only report its state.
-The command returns ERROR if it fails; otherwise, it returns OK followed by a
-number representing the current state of the flag.
-
-
- REQT   (REQuest client Termination)
-
- Request that the specified client (or all clients) log off.  Aide level
-access is required to run this command, otherwise ERROR+HIGHER_ACCESS_REQUIRED
-is returned.
-
- The REQT command accepts one parameter: the session ID of the client which
-should be terminated, or 0 for all clients.  When successful, the REQT command
-returns OK.
-
- It should be noted that REQT simply transmits an instant message to the
-specified client(s) with the EM_GO_AWAY flag set.  Older clients do not honor
-this flag, and it is certainly possible for users to re-program their client
-software to ignore it.  Therefore the effects of the REQT command should be
-considered advisory only.  The recommended implementation practice is to first
-issue a REQT command, then wait a little while (from 30 seconds up to a few
-minutes) for well-behaved clients to voluntarily terminate, and then issue a
-TERM command to forcibly disconnect the client (or perhaps a DOWN command, if
-you are logging off users for the purpose of shutting down the server).
-
-
- SEEN   (set or clear the SEEN flag for a message)
-
- 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.
-
-
- GTSN   (GeT the list of SeeN messages)
-
- 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.
-
-
- SMTP   (utility commands for the SMTP gateway)
-
- This command, accessible only by Aides, supports several utility operations
-which examine or manipulate Citadel's SMTP support.  The first command argument
-is a subcommand telling the server what to do.  The following subcommands are
-supported:
-
-      SMTP mx|hostname             (display all MX hosts for 'hostname')
-      SMTP runqueue                (attempt immediate delivery of all messages
-                                    in the outbound SMTP queue, ignoring any
-                                    retry times stored there)
-
-
- STLS   (Start Transport Layer Security)
-
- This command starts TLS on the current connection.  The current
-implementation uses OpenSSL on both the client and server end.  For future
-compatibility all clients must support at least TLSv1, and servers are
-guaranteed to support TLSv1.  During TLS negotiation (see below) the server
-and client may agree to use a different protocol.
-
- The server returns ERROR if it does not support SSL or SSL initialization
-failed on the server; otherwise it returns OK.  Once the server returns OK and
-the client has read the response, the server and client immediately negotiate
-TLS (in OpenSSL, using SSL_connect() on the client and SSL_accept() on the
-server).  If negotiation fails, the server and client should attempt to resume
-the session unencrypted.  If either end is unable to resume the session, the
-connection should be closed.
-
- This command may be run at any time.
-
-
- GTLS   (Get Transport Layer Security Status)
-
- This command returns information about the current connection.  The server
-returns OK plus several parameters if the connection is encrypted, and ERROR
-if the connection is not encrypted.  It is primarily used for debugging.  The
-command may be run at any time.
-
- 0 - Protocol name, e.g. "SSLv3"
- 1 - Cipher suite name, e.g. "ADH-RC4-MD5"
- 2 - Cipher strength bits, e.g. 128
- 3 - Cipher strength bits actually in use, e.g. 128
-
-
- IGAB   (Initialize Global Address Book)
-
- This command creates, or re-creates, a database of Internet e-mail addresses
-using the vCard information in the Global Address Book room.  This procedure
-is normally run internally when the server determines it necessary, but is
-also provided as a server command to be used as a troubleshooting/maintenenance
-tool.  Only a system Aide can run the command.  It returns OK on success or
-ERROR on failure.
-
-
- QDIR   (Query global DIRectory)
-
- Look up an internet address in the global directory.  Any logged-in user may
-call QDIR with one parameter, the Internet e-mail address to look up.  QDIR
-returns OK followed by a Citadel address if there is a match, otherwise it
-returns ERROR+NOT_LOGGED_IN.
-
-
- ISME   (find out if an e-mail address IS ME)
-
- This is a quickie shortcut command to find out if a given e-mail address
-belongs to the user currently logged in.  Its sole argument is an address to
-parse.  The supplied address may be in any format (local, IGnet, or Internet).
-The command returns OK if the address belongs to the user, ERROR otherwise.
-
-
- VIEW   (set the VIEW for a room)
-
- 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.
-
-
- QNOP   (Quiet No OPeration)
-
- This command does nothing, similar to the NOOP command.  However, unlike the
-NOOP command, it returns *absolutely no response* at all.  The client has no
-way of knowing that the command executed.  It is intended for sending
-"keepalives" in situations where a full NOOP would cause the client protocol
-to get out of sync.
-
- Naturally, sending this command to a server that doesn't support it is an
-easy way to mess things up.  Therefore, client software should first check
-the output of an INFO command to ensure that the server supports quiet noops.
-
-
-
- ICAL   (Internet CALendaring commands)
-
- This command supports a number of subcommands which are used to process the
-calendaring/scheduling support in Citadel.  Here are the subcommands which
-may be issued:
-
- ICAL test
-  Test server for calendaring support.  Always returns OK unless the server
-  does not have the calendar module enabled.
-
- ICAL respond|msgnum|partnum|action
-  Respond to a meeting request.  'msgnum' and 'partnum' refer to a MIME-encoded
-  meeting invitation in the current room.  'action' must be set to either
-  "accept" or "decline" to determine the action to take.  This subcommand will
-  return either OK or ERROR.
-
- ICAL conflicts|msgnum|partnum
-  Determine whether an incoming VEVENT will fit in the user's calendar by
-  checking it against the existing VEVENTs.  'msgnum' and 'partnum' refer to
-  a MIME-encoded meeting invitation in the current room (usually the inbox).
-  This command may return ERROR if something went wrong, but usually it will
-  return LISTING_FOLLOWS followed by a list of zero or more conflicting
-  events.  A zero-length list means that there were no conflicts.
- ICAL handle_rsvp|msgnum|partnum
-  Handle an incoming "reply" (or RSVP) to a meeting request you sent out.
-  'msgnum' and 'partnum' refer to a MIME-encoded reply in the current room.
-  'action' must be set to either "update" or "ignore" to determine the action
-  to take.  If the action is "update" then the server will hunt for the meeting
-  in the user's Calendar> room, and update the status for this attendee.  Either
-  way, the reply message is deleted from the current room.  This subcommand will
-  return either OK or ERROR.
- ICAL freebusy|username
-  Output the free/busy times for the requested user.  If the user specified
-  has a calendar available, this command will return LISTING_FOLLOWS and a
-  compound VCALENDAR object.  That object, in turn, will contain VEVENT
-  objects that have been stripped of all properties except for the bare
-  minimum needed to learn free/busy times (such as DTSTART, DTEND, and
-  TRANSP).  If there is no such user, or no calendar available, the usual
-  ERROR codes will be returned.
- ICAL sgi|<bool>
- Readers who are paying attention will notice that there is no subcommand to
-send out meeting invitations.  This is because that task can be handled
-automatically by the Citadel server.  Issue this command with <bool> set to 1
-to enable Server Generated Invitations.  In this mode, when an event is saved
-to the user's Calendar> room and it contains attendees, Citadel will
-automatically turn the event into vCalendar REQUEST messages and mail them
-out to all listed attendees.  If for some reason the client needs to disable
-Server Generated Invitations, the command may be sent again with <bool> = 0.
-
-
-
- MRTG   (Multi Router Traffic Grapher)
-
- Multi Router Traffic Grapher (please see http://www.mrtg.org for more info) is
-a tool which creates pretty graphs of network activity, usually collected from
-routers using SNMP.  However, its ability to call external scripts has spawned
-a small community of people using it to graph anything which can be graphed.
-The MRTG command can output Citadel server activity in the format MRTG expects.
-
- This format is as follows:
-
- LISTING_FOLLOWS
- Line 1: variable #1
- Line 2: variable #2
- Line 3: uptime of system
- Line 4: name of system
- 000
-
- MRTG accepts two different keywords.  "MRTG users" will return two variables,
-the number of connected users and the number of active users.  "MRTG messages"
-will return one variable (and a zero in the second field), showing the current
-highest message number on the system.  Any other keyword, or a missing keyword,
-will cause the MRTG command to return an ERROR code.
-
- Please get in touch with the Citadel developers if you wish to experiment with
-this.
-
-
-
- GNET   (Get NETwork configuration for this room)
- SNET   (Set NETwork configuration for this room)
- These commands get/set the network configuration for the current room.  Aide
-or Room Aide privileges are required, otherwise an ERROR code is returned.
-If the command succeeds, LISTING_FOLLOWS or SEND_LISTING is returned.  The
-network configuration for a specific room includes neighbor nodes with whom
-the room is shared, and mailing list recipients.  The format of the network
-configuration is described in the file "netconfigs.txt".
-
-
-
- ASYN   (ASYNchronous message support)
-
- Negotiate the use of asynchronous, or unsolicited, protocol messages.  The
-only parameter specified should be 1 or 0 to indicate that the client can or
-cannot handle this type of messages.  The server will reply OK followed by a
-1 or 0 to tell the client which mode it is now operating in.
-
- If the command is not available on the server (i.e. it returns ERROR), or
-if the command has not been executed by the client, it should be assumed that
-this mode of operation is NOT in effect.
-
- The client may also send any value other than 0 or 1 to simply cause the
-server to output its current state without changing it.
-
- When asynchronous protocol mode is in effect, the client MUST handle any
-asynchronous messages as they arrive, before doing anything else.
-
-
-
-
- ASYNCHRONOUS MESSAGES
- ---------------------
-
- When the client protocol is operating in asynchronous mode (please refer to
-the writeup of the ASYN command above), the following messages may arrive at
-any time:
-
-
- 902  (instant message arriving)
-
- One or more instant messages have arrived for this client.