From 20c845a1bfdc8efe9299ba273b291c32433da485 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sun, 12 Jul 1998 22:46:02 +0000 Subject: [PATCH] These were moved to the 'techdoc' subdirectory. These are existing files. They were merely moved into this directory. --- citadel/techdoc/hack.txt | 474 +++++++++++ citadel/techdoc/session.txt | 1583 +++++++++++++++++++++++++++++++++++ 2 files changed, 2057 insertions(+) create mode 100644 citadel/techdoc/hack.txt create mode 100644 citadel/techdoc/session.txt diff --git a/citadel/techdoc/hack.txt b/citadel/techdoc/hack.txt new file mode 100644 index 000000000..9a1cca4d0 --- /dev/null +++ b/citadel/techdoc/hack.txt @@ -0,0 +1,474 @@ + hack.doc for Citadel/UX + written by Art Cancro (ajc@uncnsrd.mt-kisco.ny.us) + + Much of this document is borrowed from the original hack.doc from +Citadel-CP/M and Citadel-86, because many of the concepts are the same. Hats +off to whoever wrote the original, for a fine document that inspired the +implementation of Citadel for Unix. + + Note that this document is really out of date. It doesn't cover anything +about the threaded server architecture or any of the network stuff. What is +covered here is the basic architecture of the databases. + + But enough of the preamble. Here's how Citadel/UX works :) + + Here are the major databases to be discussed: + + msgmain The big circular file that contains message text + quickroom Contains room info such as room names, stats, etc. + fullroom One fullrm file per room: message numbers and pointers. + usersupp Contains info for each user on the system. + + The fundamental structure of the system differs greatly from the way +Citadels used to work. Citadel now depends on a record manager or database +manager of some sort. Thanks to the API which is in place for connecting to +a data store, any record manager may be used as long as it supports the +storage and retrieval of large binary objects (blobs) indexed by unique keys. +Please see database.c for more information on data store primitives. + + The message base (msgmain) is a big file of messages indexed by the message +number. Messages are numbered consecutively and start with an FF (hex) +byte. Except for this FF start-of-message byte, all bytes in the message +file have the high bit set to 0. This means that in principle it is +trivial to scan through the message file and locate message N if it +exists, or return error. (Complexities, as usual, crop up when we +try for efficiency...) + + Each room is basically just a list of message numbers. Each time +we enter a new message in a room, we slide all the old message-numbers +down a slot, and probably the oldest one falls off the bottom (in which case +we must delete it from the message base). Reading a rooms is just a matter +of looking up the messages one by one and sending them to the client for +display, printing, or whatever. + + Implementing the "new message" function is also trivial in principle: +we just keep track, for each caller in the userlog, of the highest-numbered +message which existed on the >last< call. (Remember, message numbers are +simply assigned sequentially each time a message is created. This +sequence is global to the entire system, not local within a room.) If +we ignore all message-numbers in the room less than this, only new messages +will be printed. Voila! + + message format on disk (msgmain) + + Each message begins with an FF byte. The next byte will then be MES_NORMAL, +MES_ANON, or MES_ANON2, depending on whether the message in anonymous or not. +The next byte is either a 0 or 1. If it is 0, the message will be printed +with the Citadel formatter. If it is a 1, the +message is printed directly to the screen, as is. External editors generate +this type of message. After these three opening bytes, the remainder of +the message consists of a sequence of character strings. Each string +begins with a type byte indicating the meaning of the string and is +ended with a null. All strings are printable ASCII: in particular, +all numbers are in ASCII rather than binary. This is for simplicity, +both in implementing the system and in implementing other code to +work with the system. For instance, a database driven off Citadel archives +can do wildcard matching without worrying about unpacking binary data such +as message ID's first. To provide later downward compatability +all software should be written to IGNORE fields not currently defined. + + The type bytes currently defined are: + +BYTE Mnemonic Comments + +T Date/Time A 32-bit integer containing the date and time of + the message in standard UNIX format (the number + of seconds since January 1, 1970 GMT). +P Path Complete path of message, as in the UseNet news + standard. A user should be able to send UUCP mail to + this path. (Note that your system name will not be + tacked onto this until you're sending the message to + someone else) +I ID on orig A 32-bit integer containing the message ID on the + system the message *originated* on. +# ID on local A 32-bit integer containing the message ID on the + system the message is *currently* on (obviously this + is meaningless for a message being transmitted over + a network). +A Author Name of originator of message. +E EmailUserID Only present in messages originating from the Internet. + It contains the username portion of the author's + e-mail address, thereby allowing replies and bounces + to be properly formulated. +R Recipient Only present in Mail messages. +O Room Room of origin. +N Nodename Contains node name of system message originated on. +H HumanNodeName Contains human name of system message originated on. +D Destination Contains name of the system this message should + be sent to, for mail routing (private mail only). +U Subject Optional. Developers may choose whether they wish to + generate or display subject fields. Citadel/UX does + not generate them, but it does print them when found. +B Phone number The dialup number of the system this message + originated on. This is optional, and is only + defined for helping implement C86Net gateways. +G Gateway domain This field is provided solely for the implementation + of C86Net gateways, and holds the C86Net domain of + the system this message originated on. Unless you're + implementing such a gateway, there's no need to even + bother with this field. +S Special field Only meaningful for messages being spooled over a + network. Usually means that the message isn't really + a message, but rather some other network function: + -> "S" followed by "FILE" (followed by a null, of + course) means that the message text is actually an + IGnet/Open file transfer. +M Message Text Normal ASCII, newlines seperated by CR's or LF's, + null terminated as always. + + EXAMPLE + +Let be a 0xFF byte, and <0> be a null (0x00) byte. Then a message +which prints as... + +Apr 12, 1988 23:16 From Test User In Network Test> @lifesys (Life BBS) +Have a nice day! + + might be stored as... +<40><0>I12345<0>Pneighbor!lifesys!test_user<0>T576918988<0> (continued) +-----------|Mesg ID#|--Message Path---------------|--Date------ + +AThe Test User<0>ONetwork Test<0>Nlifesys<0>HLife BBS<0>MHave a nice day!<0> +|-----Author-----|-Room name-----|-nodename-|Human Name-|--Message text----- + + Weird things can happen if fields are missing, especially if you use the +networker. But basically, the date, author, room, and nodename may be in any +order. But the leading fields and the message text must remain in the same +place. The H field looks better when it is placed immediately after the N +field. + + Networking + +Citadel nodes network by sharing one or more rooms. Any Citadel node +can choose to share messages with any other Citadel node, through the sending +of spool files. The sending system takes all messages it hasn't sent yet, and +spools them to the recieving system, which posts them in the rooms. + +Complexities arise primarily from the possibility of densely connected +networks: one does not wish to accumulate multiple copies of a given +message, which can easily happen. Nor does one want to see old messages +percolating indefinitely through the system. + +This problem is handled by keeping track of the path a message has taken over +the network, like the UseNet news system does. When a system sends out a +message, it adds its own name to the bang-path in the

field of the +message. If no path field is present, it generates one. + +With the path present, all the networker has to do to assure that it doesn't +send another system a message it's already received is check the

ath field +for that system's name somewhere in the bang path. If it's present, the system +has already seen the message, so we don't send it. (Note that the current +implementation does not allow for "loops" in the network -- if you build your +net this way you will see lots of duplicate messages.) + +The above discussion should make the function of the fields reasonably clear: + + o Travelling messages need to carry original message-id, system of origin, + date of origin, author, and path with them, to keep reproduction and + cycling under control. + +(Uncoincidentally) the format used to transmit messages for networking +purposes is precisely that used on disk, except that there may be any amount +of garbage between the null ending a message and the starting the next +one. This allows greater compatibility if slight problems crop up. The current +distribution includes netproc.c, which is basically a database replicator; +please see network.txt on its operation and functionality (if any). + + portability problems + + At this point, most hardware-dependent stuff has been removed from the +system. On the server side, most of the OS-dependent stuff has been isolated +into the sysdep.c source module. The server should compile on any POSIX +compliant system with a full pthreads implementation and TCP/IP support. In +the future, we may try to port it to non-POSIX systems as well. + + On the client side, it's also POSIX compliant. The client even seems to +build ok on non-POSIX systems with porting libraries (such as the Cygnus +Win32 stuff). + + + "Room" records (quickroom/fullroom) + +The rooms are basically indices into msgmain, the message database. +As noted in the overview, each is essentially an array of pointers into +the message file. The pointers consist of a 32-bit message ID number +(we will wrap around at 32 bits for these purposes). + +Since messages are numbered sequentially, the +set of messages existing in msgmain will always form a continuous +sequence at any given time. + +That should be enough background to tackle a full-scale room. From citadel.h: + +STRUCT QUickroom { + char QRname[20]; /* Max. len is 19, plus null term */ + char QRpasswd[10]; /* Only valid if it's a private rm */ + long QRroomaide; /* User number of room aide */ + long QRhighest; /* Highest message NUMBER in room */ + char QRgen; /* Generation number of room */ + unsigned QRflags; /* See flag values below */ + char QRdirname[15]; /* Directory name, if applicable */ + char QRfloor; /* (not yet implemented) */ + }; + +#define QR_BUSY 1 /* Room is being updated, WAIT */ +#define QR_INUSE 2 /* Set if in use, clear if avail */ +#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 users only */ + +struct fullroom { + long FRnum[MSGSPERRM]; /* Message NUMBERS */ + }; + +[Note that all components start with "QR" for quickroom, to make sure we + don't accidentally use an offset in the wrong structure. Be very careful + also to get a meaningful sequence of components -- + some C compilers don't check this sort of stuff either.] + +QRgen handles the problem of rooms which have died and been reborn +under another name. This will be clearer when we get to the userlog. +For now, just note that each room has a generation number which is +bumped by one each time it is recycled. + +QRflags is just a bag of bits recording the status of the room. The +defined bits are: + +QR_BUSY This is to insure that two processes don't update the same + record at the same time, even though this hasn't been + implemented yet. +QR_INUSE 1 if the room is valid, 0 if it is free for re-assignment. +QR_PRIVATE 1 if the room is not visible by default, 0 for public. +QR_PASSWORDED 1 if entry to the room requires a password. +QR_GUESSNAME 1 if the room can be reached by guessing the name. +QR_DIRECTORY 1 if the room is a window onto some disk/userspace, else 0. +QR_UPLOAD 1 if users can upload into this room, else 0. +QR_DOWNLOAD 1 if users can download from this room, else 0. +QR_VISDIR 1 if users are allowed to read the directory, else 0. +QR_ANONONLY 1 if all messages are to recieve the "****" anon header. +QR_ANON2 1 if the user will be asked if he/she wants an anon message. +QR_NETWORK 1 if this room is shared on a network, else 0. +QR_PREFONLY 1 if the room is only accessible to preferred users, else 0. + +QRname is just an ASCII string (null-terminated, like all strings) +giving the name of the room. + +QRdirname is meaningful only in QR_DIRECTORY rooms, in which case +it gives the directory name to window. + +QRpasswd is the room's password, if it's a QR_PASSWORDED room. Note that +if QR_PASSWORDED or QR_GUESSNAME are set, you MUST also set QR_PRIVATE. +QR_PRIVATE by itself designates invitation-only. Do not EVER set all three +flags at the same time. + +QRroomaide is the user number of the room's room-aide (or zero if the room +doesn't have a room aide). Note that if a user is deleted, his/her user number +is never used again, so you don't have to worry about a new user getting the +same user number and accidentally becoming a room-aide of one or more rooms. + +The only field new to us in quickroom is QRhighest, recording the +most recent message in the room. When we are searching for rooms with +messages a given caller hasn't seen, we can check this number +and avoid a whole lot of extra disk accesses. + + The fullroom is the array of pointers into the message file. We keep one +file for each fullroom array to keep the quickroom file small (and access time +efficient). FRnum are the message numbers on disk of +each message in the room. (For NIL, we stick zeroes in both fields.) + + user records (usersupp) + +This is the fun one. Get some fresh air and plug in your thinking cap +first. (Time, space and complexity are the usernum software rivals. +We've got lots of log entries times lots of messages spread over up to nnn +rooms to worry about, and with multitasking, disk access time is important... +so perforce, we opt for complexity to keep time and space in bounds.) + +To understand what is happening in the log code takes a little persistence. +You also have to disentangle the different activities going on and +tackle them one by one. + + o We want to remember some random things such as terminal screen + size, and automatically set them up for each caller at login. + + o We want to be able to locate all new messages, and only new + messages, efficiently. Messages should stay new even if it + takes a caller a couple of calls to get around to them. + + o We want to remember which private rooms a given caller knows + about, and treat them as normal rooms. This means mostly + automatically seeking out those with new messages. (Obviously, + we >don't< want to do this for unknown private rooms!) This + has to be secure against the periodic recycling of rooms + between calls. + + o We want to support private mail to a caller. + + o We want to provide some protection of this information (via + passwords at login) and some assurance that messages are from + who they purport to be from (within the system -- one shouldn't + be able to forge messages from established users). + +Lifting another page from citadel.h gives us: + +struct usersupp { /* User record */ + int USuid; /* uid account is logged in under */ + char password[20]; /* password (for BBS-only users) */ + long lastseen[MAXROOMS]; /* Last message seen in each room */ + char generation[MAXROOMS]; /* Generation # (for private rooms) */ + char forget[MAXROOMS]; /* Forgotten generation number */ + long mailnum[MAILSLOTS]; /* Message #'s of each mail message */ + long mailpos[MAILSLOTS]; /* Disk positions of each mail */ + unsigned flags; /* See US_ flags below */ + int screenwidth; /* For formatting messages */ + int timescalled; /* Total number of logins */ + int posted; /* Number of messages posted (ever) */ + char fullname[26]; /* Bulletin Board name for messages */ + char axlevel; /* Access level */ + char spare[3]; /* spare bytes for future use */ + long usernum; /* Eternal user number */ + long lastcall; /* Last time the user called */ + }; + +#define US_PERM 1 /* Permanent user; don't scroll off */ +#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_PREF 1024 /* Preferred user */ + +Looks simple enough, doesn't it? One topic at a time: + + Random configuration parameters: +-screenwidth is the caller's screen width. We format all messages to this +width, as best we can. flags is another bit-bag, recording whether we want +prompts, people who want to suppress the little automatic hints all through +the system, etc. + + Attachments, names & numbers: +-USuid is the uid the account was established under. For most users it will +be the same as BBSUID, but it won't be for users that logged in from the shell. +-fullname is the user's full login name. +-usernum is the user's ID number. It is unique to the entire system: +once someone has a user number, it is never used again after the user is +deleted. This allows an easy way to numerically represent people. +-password is the user's password. +-axlevel is the user's access level, so we know who's an Aide, who's a problem +user, etc. These are defined and listed in the system. + + Feeping Creatures: +-timescalled is the number of times the user has called. +-posted is the number of messages the user has posted, public or private. + + Misc stuff: +-lastcall holds the date and time (standard Unix format) the user called, so +we can purge people who haven't called in a given amount of time. + + Finding new messages: +This is the most important. Thus, it winds up being the most +elaborate. Conceptually, what we would like to do is mark each +message with a bit after our caller has read it, so we can avoid +printing it out again next call. Unfortunately, with lots of user +entries this would require adding lots of bits to each message... and +we'd wind up reading off disk lots of messages which would never +get printed. So we resort to approximation and a small table. + +The approximation comes in doing things at the granularity of +rooms rather than messages. Messages in a given room are "new" +until we visit it, and "old" after we leave the room... whether +we read any of them or not. This can actually be defended: anyone +who passes through a room without reading the contents probably just +isn't interested in the topic, and would just as soon not be dragged +back every visit and forced to read them. Given that messages are +numbered sequentially, we can simply record the most recent message ID# +of each room as of the last time we visited it. Very simple. + +Putting it all together, we can now compute whether a given room +has new messages for our current caller without going to the message base +index (fullroom) at all: + + > We get the usersupp.lastseen[] for the room in question + > We compare this with the room's quickroom.QRhighest, which tells us + what the most recent message in the room is currently. + + + REMEMBERING WHICH PRIVATE ROOMS TO VISIT + +This looks trivial at first glance -- just record one bit per room per +caller in the log records. The problem is that rooms get recycled +periodically, and we'd rather not run through all the log entries each +time we do it. So we adopt a kludge which should work 99% of the time. + +As previously noted, each room has a generation number, which is bumped +by one each time it is recycled. As not noted, this generation number +runs from 0 -> 127 (and then wraps around and starts over). + When someone visits a room, we set usersupp.generation for the room +equal to that of the room. This flags the room as being available. +If the room gets recycled, on our next visit the two generation numbers +will no longer match, and the room will no longer be available -- just +the result we're looking for. (Naturally, if a room is public, +all this stuff is irrelevant.) + +This leaves only the problem of an accidental matchup between the two +numbers giving someone access to a Forbidden Room. We can't eliminate +this danger completely, but it can be reduced to insignificance for +most purposes. (Just don't bet megabucks on the security of this system!) +Each time someone logs in, we set all "wrong" generation numbers to -1. +So the room must be recycled 127 times before an accidental matchup +can be achieved. (We do this for all rooms, INUSE or dead, public +or private, since any of them may be reincarnated as a Forbidden Room.) + +Thus, for someone to accidentally be led to a Forbidden Room, they +must establish an account on the system, then not call until some room +has been recycled 127 to 128 times, which room must be +reincarnated as a Forbidden Room, which someone must now call back +(having not scrolled off the userlog in the mean time) and read new +messages. The last clause is about the only probable one in the sequence. +The danger of this is much less than the danger that someone will +simply guess the name of the room outright (if it's a guess-name room) +or some other human loophole. + + FORGOTTEN ROOMS + + This is exactly the opposite of private rooms. When a user chooses to +forget a room, we put the room's generation number in usersupp.forget for +that room. When doing a nown rooms list or a oto, any matchups cause +the room to be skipped. Very simple. + + SUPPORTING PRIVATE MAIL + +Can one have an elegant kludge? This must come pretty close. + +Private mail is sent and recieved in the Mail> room, which otherwise +behaves pretty much as any other room. To make this work, we store +the actual message pointers in mailnum[] and mailpos[] in the caller's +log record, and then copy them into the Mail> room array whenever we +enter the room. This requires a little fiddling to get things just +right. We have to update quickroom[1].QRhighest at login +to reflect the presence or absence of new messages, for example. And +make_message() has to be kludged to ask for the name of the recipient +of the message whenever a message is entered in Mail>. But basically +it works pretty well, keeping the code and user interface simple and +regular. + + + PASSWORDS AND NAME VALIDATION + + This has changed a couple of times over the course of Citadel's history. At +this point it's very simple, again due to the fact that record managers are +used for everything. The user file (usersupp) is indexed using the user's +name, converted to all lower-case. Searching for a user, then, is easy. We +just lowercase the name we're looking for and query the database. If no +match is found, it is assumed that the user does not exist. + + This makes it difficult to forge messages from an existing user. (Fine +point: nonprinting characters are converted to printing characters, and +leading, trailing, and double blanks are deleted.) diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt new file mode 100644 index 000000000..1cc3c2144 --- /dev/null +++ b/citadel/techdoc/session.txt @@ -0,0 +1,1583 @@ + SESSION LAYER PROTOCOL FOR CITADEL/UX + (c) 1995-1998 by Art Cancro All Rights Reserved + + + INTRODUCTION + ------------ + + This is an attempt to document the session layer protocol used by the +Citadel/UX 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/UX project is Art Cancro . + + + CONNECTING TO A SERVER + ---------------------- + + The protocols used below the session layer are beyond the scope of this +document, but we will briefly cover a few of the currently used methods. +Keep in mind that the server program itself does not speak any protocols +lower than the session layer. Instead, it reads all input from stdin, and +writes all output to stdout. This implies that it is the responsibility of +other programs to provide a usable transport to the client programs. + + One way to connect to a server is to use a set of pipes. This does of +course assume that the client and server are running on the same computer. +When the client starts up, the first thing that it does is create two pipes, +which it temporarily dup()'s to stdin and stdout. Then it proceeds to +fork() and exec() to a copy of the server program, which inherits the +pipes as its standard input and output - exactly the desired effect. The +client program can then re-connect its own stdin and stdout to where they're +supposed to be, and use the pipes to send and receive server messages. + + Another way is to use TCP/IP. Under Unix-like systems this is easily +accomplished using the "inetd" superserver program, which can take programs +like the Citadel/UX server and offer connections to clients over a TCP or +UDP port. See the install documentation (or the inetd documentation from +your OS) for information on how to do this. Always use TCP ports for +Citadel/UX sessions. Since our session layer assumes a clean, reliable, +sequenced connection, the use of UDP would render the server unstable and +unusable. When operating in a TCP/IP environment, the port number officially +assigned to Citadel is 504. + + + 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.) We do this to allow the server to +function over transports which can only handle one session at a time (such +as a dialup connection). + + + 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. + + + 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/UX 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 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, +or if a USER command has not been executed yet, ERROR 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 + + + 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, or ERROR if another user already exists with this name. If OK, +it will also return the same parameters that PASS returns. + + + AUTO (AUTOmatic login **OBSLETE** ) + + Citadel/UX no longer supports this type of authentication. It was formerly +used to automatically authenticate a user based on the user ID under which +the server was running. Due to the new multithreaded architecture of the +server, this is no longer possible. + + + 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. + + + LKRN (List Known Rooms with New messages) + + List known rooms with new messages. If the client is not logged in, ERROR +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 */ + + + Other bits may be defined in the future. The listing terminates, as with +all listings, with "000" on a line by itself. + + Version 4.01 and above only: + + 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. + + + + 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. + + + GETU (GET User configuration) + + This command retrieves the screen dimensions and user options for the +currently logged in account. ERROR will be returned if no user is logged +in, of course. Otherwise, OK will be returned, followed by three 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). + + 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. + + Citadel/UX server v4.01 and above, also has two additional reserved room +names. "_MAIL_" translates to the system's designated room for e-mail +messages, and "_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 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. + NO_SUCH_ROOM - 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). + + ...and in server 4.01 and above: + 9. The number of new Mail messages the user has (useful for alerting the +user to the arrival of new mail during a session) + + ...and in server 4.03 and above: + 10. The floor number this room resides on + + + 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/UX 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. + + This command can return two possible results. An ERROR code may be returned +if no user is currently logged in or if something else went wrong. 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. + + + 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. In server +version 4.04 and above, the second argument may be set to either 0 to read the +entire message, or 1 to read the headers only. + + The server should, of course, make sure that the client actually has access +to the message being requested before honoring this request. Citadel/UX does +so by checking the message number against the contents of the current room. If +it's not there, the request is denied. + + If the request is denied, an ERROR code will be returned. Otherwise, the +LISTING_FOLLOWS code will be returned, followed by the contents of the message. +The following fields may be sent: + + type= Formatting type. Currently, there are two defined types. Type 0 is +"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. +Type 1 is 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. + + 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. + + 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/UX 4.00" + Line 6 - (The revision level of the server code) * 100 + Line 7 - The geographical location of the BBS (for USA: city and state) + 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 + + (version 4.01 and above only) + Line 11 - Floor Flag. 1 if the system supports floors, 0 otherwise. + + *** 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 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/UX program, so everyone can enjoy it. + + 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. The server type +codes currently defined are: + + Type Developer + ---- --------------------------------------- + 0 Art Cancro + 1 Brian Ledbetter + 2 Matthew Scott + 3 Jesse Vincent + 4 Brian Costello + 5 Robert Abatecola + + + + 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, or some other error; 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; 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: + uncnsrd.mt-kisco.ny.us|/usr/bbs/files/my_room_directory + + + SLRP (Set Last-message-Read Pointer) + + This command is used to mark messages as having been read. 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 oto command). + + The command will return OK if the pointer was set, or ERROR if something +went wrong. 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, or ERROR if it did +not. ERROR+HIGHER_ACCESS_REQUIRED may also 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 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. + ERROR+NOT_HERE - Lobby>, Mail>, and Aide> cannot be edited. + 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) + + (And on server version 4.01 and above ... ) + 4. The floor number on which the room resides + + + 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) + + (And on server version 4.01 and above, the client may also send ... ) + 5. The floor number on which the room should reside + + *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. + + 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, ERROR if there +is no current room, or OK if the command succeeded. Along with OK there will +be returned one parameter: the name of the Room Aide. + + + 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/UX, 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 (No current room, or room cannot be edited. +Under Citadel/UX, the Lobby> Mail> and Aide> rooms are non-editable.) + 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 "apparant" post name if the user is privileged enough. +This post name is arg 4. + 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/UX format type may be used (this will +typically be 0; see the MSG0 command above). + 4 - 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 - Miscellaneous error. (Explanation probably follows.) + 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. + + + MOVE (MOVE a message to a different room) + + Move a message to a different room. The two arguments that should be passed +to this command are the message number of the message to be deleted, and the +name of the target room. If the operation succeeds, the message will be +deleted from the current room and moved to the target room. An ERROR code +usually means that either the user does not have permission to perform this +operation, or that the target room does not exist. + + + 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") + 3 - Password for new room (if it is a type 2 room) + 4 - Floor number on which the room should reside (optional, and in server + version 4.01 and above only) + + 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/UX 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/UX provides these for the Citadel/UX 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 + + 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 + + + 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 + + + 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/UX 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). + + 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, and (in version 5.00 and above) the time of last +modification. + + + 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/UX, 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/UX 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). + + + + --------------------------------------------------------------------------- + The following commands are available only in Citadel/UX server version 4.01 + and above. + --------------------------------------------------------------------------- + + NETP (authenticate as network session with system 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 system net +password for the server. If the authentication succeeds, NETP will return +OK, otherwise, it returns ERROR. + + + 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) + + --------------------------------------------------------------------------- + The following commands are available only in Citadel/UX server version 4.02 + and above. + --------------------------------------------------------------------------- + +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. + + --------------------------------------------------------------------------- + The following commands are available only in Citadel/UX server version 4.03 + and above. + --------------------------------------------------------------------------- + +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 networker (netproc.c) logs onto the server as an +internal program in order to fetch and store messages. 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/UX 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 will send the msg to 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 EXPress messages) + + This is one of two commands which implement "express messages" (also known +as "paging"). An express message is a near-real-time message sent from one +logged in user to another. When an express message is sent, it will be +displayed the next time the target user executes a PEXP 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. + + In Citadel/UX 5.00 and above, the reserved name "broadcast" may be used +instead of a user name, to broadcast an express message to all users +currently connected to the server. + + Do be aware that if an express message is transmitted to a user who is logged +in using a client that does not check for express messages, the message will +never be received. + + + PEXP (Print EXPress messages) + + This command, called without any arguments, simply dumps out the contents +of any waiting express 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 express 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 express messages. + + --------------------------------------------------------------------------- + The following commands are available only in Citadel/UX server version 4.10 + and above. + --------------------------------------------------------------------------- + + 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, +ERROR+NO_SUCH_USER if the named user does not exist, or ERROR+FILE_NOT_FOUND +if the user exists but has no bio on file. + + --------------------------------------------------------------------------- + The following commands are available only in Citadel/UX server version 4.11 + and above. + --------------------------------------------------------------------------- + + 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. + +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/UX 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. + + --------------------------------------------------------------------------- + The following commands are available only in Citadel/UX server version 5.00 + and above. + --------------------------------------------------------------------------- + + 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. + + + ENT3 (ENTer message, mode 3 -- internal command) + + ENT3 is for use by internal programs only and should not be utilized by +user-mode clients. It does require IPGM authentication. This command posts +a raw message straight into the message base without modification or performing +any checks. It accepts the following 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. This is used to verify the operation +before actually transmitting a message. + 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 - The size (in bytes) of the message to be transmitted. + + ENT3 returns OK to tell the client that a message can be posted, ERROR if +there would be a problem with the operation, or SEND_BINARY followed by a byte +count if it is expecting the message to be transmitted. + + + 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. + + + NSET (Network SETup commands) + + Aides may use this command to configure the networker. This command's +parameters are passed directly to the 'netsetup' command line utility. If +netsetup returns a non-zero exit code, ERROR is returned, along with the +error message (if any). If netsetup returns a zero (success) exit code, +LISTING_FOLLOWS is returned, followed by zero or more lines of output (since +netsetup may have information to display, such as a room or node list) and +the usual '000' listing terminator. + + + 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/UX, 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. + +---------------------------------------------- +The following are for citserver 5.02 and above +---------------------------------------------- + +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 see an entry right underneath the spoofed +entry listing the actual hostname the user originates from. + +The format of an HCHG command is: + +HCHG + + +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 see an entry right underneath the spoofed entry listing +the actual room the user is in. + +The format of an RCHG command is: + +RCHG + +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 + +If a UCHG command is successful, the value OK (200) is returned. + +TIME (Get server local TIME) + +TIME returns a string in the following format: + + A|B + +Where A is OK (200), B is the current time measured in seconds since +00:00:00 GMT, Jan 1, 1970. + +This is used in allowing a client to calculate idle times. + -- 2.30.2