eric@sactoh0.SAC.CA.US (Eric J. Nihill) (11/26/90)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # docs # This archive created: Sun Nov 25 12:49:02 1990 export PATH; PATH=/bin:/usr/bin:$PATH if test ! -d 'docs' then echo shar: "creating directory 'docs'" mkdir 'docs' fi echo shar: "entering directory 'docs'" cd 'docs' echo shar: "extracting 'copyright.doc'" '(1148 characters)' if test -f 'copyright.doc' then echo shar: "will not over-write existing file 'copyright.doc'" else cat << \SHAR_EOF > 'copyright.doc' Citadel/UX release 3.01-1d Copyright (c) 1989 by Art Cancro @ Westchester Data Control Systems All Rights Reserved This package may be used by anyone for any reason and distributed as widely as possible provided no financial compensation for the package is imposed. Modifications made to the package may NOT be distributed, in any format, without written permission from the author. Use of this package certifies your agreement to comply by the licence rules outlined in this file. The author assumes no responsibility for the effects of any programs included in this package on any of the user's hardware or software. This package is user supported shareware. Its contents represent countless hours of work. If you do set up a system using this release, please send a contribution of $20 to: Westchester Data Control Systems One Kirby Plaza East White Plains, NY 10604-2718 ATTN: Citadel/UX communications UNIX is a trademark of AT&T / Xenix is a trademark of Microsoft, Inc. SHAR_EOF fi echo shar: "extracting 'hack.doc'" '(22466 characters)' if test -f 'hack.doc' then echo shar: "will not over-write existing file 'hack.doc'" else cat << \SHAR_EOF > 'hack.doc' hack.doc for Citadel/UX written by Art Cancro / October 1988 Most of this document was taken from the original hack.doc from Citadel-CP/M and Citadel-86. Most of the concepts used in Citadel/UX are the same, but the filenames and structures are different. Here are the major files 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 is very simple. msgmain is a circular file. New messages are simply written around the buffer in an endless circle, overwriting old messages in their way. There is no other way of deleting messages, and text is never shuffled on disk. 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. Reading a room is just a matter looking up the messages one by one and printing them out. If the message has been overwritten already, we just ignore it. 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 formatter as usual. If it is a 1, the message is dumped byte by byte directly to the screen. 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 dates 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 long containing the date and time of the message in standard UNIX format (the number of seconds since January 1, 1970) P Path Complete path of message, as in the UseNet news protocol. 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 long containing the message ID on the system the message originated on. A Author Name of originator of message. R Recipient Only present in Mail messages. O Room Room of origin. N Nodename Contains name of system message originated on. D Destination Contains name of the system this message should be sent to, for mail routing. M Message Text Normal ASCII, newlines seperated by CR's or LF's, null terminated as always. EXAMPLE Let <FF> be a 0xFF byte, and <0> be a null (0x00) byte. Then a message which prints as... Apr 12, 1988 23:16 From Test User In Network Test> @lifesys Have a nice day! might be stored as... <FF><40><0>I12345<0>Pneighbor!lifesys!test_user<0>T576918988<0> (continued) -----------|Mesg ID#|--Message Path---------------|--Date------ AThe Test User<0>ONetwork Test<0>Nlifesys<0>MHave a nice day!<0> |-----Author-----|-Room name-----|-nodename-|--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. Networking Citadel nodes network by sharing one or more rooms via uucp. 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 a simple brute-force mechanism: each node keeps a list of all messages it has seen recently, recording origin system, creation date, and author. When processing recieved messages, ones which have already been seen, or which are too old to be remembered, are skipped. Messages can percolate outward through a large network with no global routing or control, but do not reproduce wildly or cycle indefinitely. Also, when sending messages to another system, the networker can look at a message's P (path) field for the receiving system's name. If it finds it, the system already has seen that message, so it doesn't send it a new copy. Note that some older versions do not support the P field, so make sure that it works adequately without this last feature (although it should be implemented because it saves lots of connect time). 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, and author with them, to keep reproduction and cycling under control. Path is highly reccomended. (Uncoincidentally) the format used to transmit messages for networking purposes is precisely that used on disk, except that there may be any amount of garbage between the null ending a message and the <FF> starting the next one. This allows greater compatibility if slight problems crop up. The current distribution includes netproc.c, which is basically a database integrator; please see network.doc on its operation and functionality (if any). portability problems The major problem seems to be that no two tty devices are exactly alike. You will probably need to adjust the settings to fit your system; check the sttybbs() routine for this. "Room" records (quickroom/fullroom) The rooms are basically indices into msgmain, the message file. 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) together with a 32-bit file pointer within msgmain telling us where the message begins. Since messages are numbered sequentially and written circularly, the set of messages existing in msgmain will always form a continuous sequence at any given time. Thus, by remembering the ID numbers of the oldest and newest messages in the message file, we can check to see if a message exists >before< going to msgmain, saving ourselves (and the disk drive) the pain of futile seeks in search of the nonexistent. This information is recorded in oldest and newest, 32 bit numbers. You'll be seeing more of these... The newest is simply incremented each time we enter a new message in the message files. Oldest is incremented each time we overwrite an FF (start-of-message) byte in the course of writing a new message into the files. This corresponds to dead reckoning -- current code never checks to see that the message number of the message we are overwriting is what we think it is. In a garbaged file with extra FF bytes around, this could cause oldest to count too rapidly, eventually perhaps overtaking newest, at which time the system will look completely empty. This should never happen, but it's always safe to take backups. 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 */ }; #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 */ long FRpos[MSGSPERRM]; /* Message POSITIONS in master file */ }; [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 -- there is no checking on 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 and FRpos are the message numbers and positions 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 eternal software rivals. We've got lots of log entries x lots of messages spread over up to 100 rooms to worry about, and with multiuser disk access time is important... so perforce, we opt for lots of 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[30]; /* Bulletin Board name for messages */ long eternal; /* Eternal user number */ long lastcall; /* Last time the user called */ }; #define US_PERM 1 /* Permanent user; don't scroll off */ #define US_AIDE 2 /* Aide privileges */ #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_TWIT 256 /* Problem user */ #define US_NONET 512 /* Deny this user net privileges */ #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, "problem users," 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. -eternal is the user's "eternal" user number. It is called eternal because 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. It is only requested if the user does not have shell access and is BBS-only. 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 space 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 lots of storage. 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 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 lead 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 meet the right (wrong?) people and get into the room anyway... 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 <K>nown rooms list or a <G>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 The usersupp file is kept in alphabetical order, allowing us to do a binary search whenever we need to look up a user. When a new user logs in, he/she has to be inserted into the proper alphabetical place. Just in case something goes wrong, a "sort userlog" command is included in sysoputil, although it never really gets used. So when a user types his/her login name, or when we're looking up a mail recipient, or anything else which requires finding a usersupp entry for a given login name, all we have to do is do a binary search. The routine finduser() does this quickly and efficiently. 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.) SHAR_EOF fi echo shar: "extracting 'install.doc'" '(5061 characters)' if test -f 'install.doc' then echo shar: "will not over-write existing file 'install.doc'" else cat << \SHAR_EOF > 'install.doc' Citadel/UX Installation Procedure Written by Art Cancro [Inspector Gadget @ UNCENSORED! (914) 761-6877] See copyright.doc for copyright information OVERVIEW Citadel/UX is a bulletin board system based on, but not ported from, the Citadel-CP/M and Citadel-86 systems. It was developed on an Altos 586/40 running Altos Xenix 3.0b, and has been installed and tested on various UNIX and Xenix systems, including various System III and System V ports. The current distribution includes: - The Citadel/UX main program - A networker that utilizes UUCP and can share messages with other Citadel/UX systems, as well as UseNet sites (a StoneHenge networker is available by special request) - A program to allow logged in users to chat with whoever is on the console - Setup programs - Various sysop utilities, and a shell script menu to select them from - Documentation Some knowledge of the UNIX system is necessary to install and manage the system. It is preferable that the sysop have superuser access to the operating system. The following are required to install Citadel/UX: - Some sort of UNIX-based operating system - C compiler - make (if you wish to utilize the Makefile, else compile manually) - The "curses" library (two of the utilities utilize cursor control) - Enough disk space to hold all of the programs and data EVERYTHING IN ITS PLACE... Hopefully you've unpacked the distribution archive into its own directory. This is the directory in which all Citadel files are located and in which all BBS activity will take place. Several subdirectories have already been created during the unpacking process, and others may be created by the software if needed. THE BBS LOGIN There will be one account in /etc/passwd which all BBS users will use to login to the system. This account is typically called "bbs" or "citadel" or something to that effect. You will tell Citadel what the user-id of that account is, and when someone logs in under that account, Citadel will prompt for a user name. For all other users in /etc/passwd, Citadel will automatically set up an account using the "full name" field. No password is required, since it assumes that if a user is logged in, he/she has already entered a password. The BBS login should have a unique uid. The home directory should be the one your BBS resides in (in this example we will use /usr/bbs) and the shell should be citadel in that directory. Here is an example: bbs::7:1:BBS Login:/usr/bbs:/usr/bbs/citadel When we edit the sysconfig.h file, we will tell Citadel what the BBS login's uid is, so it knows when to prompt for a name and password. SYSTEM CONFIGURATION FILE (sysconfig.h) You MUST edit sysconfig.h BEFORE you compile any of your programs. It's massively self-documented; just read the file and edit it as it tells you. You can change some of the ways the program runs with this file, as well as configure how big the system is going to be. There is a section labelled "structure size variables" that will select how many rooms will fit in the system, how many mail slots each user has, etc. Note that you CANNOT change these without wiping out your own system, so only set them ONCE. Once you have edited sysconfig.h, you may then compile all of the programs. This can be done using the makefile supplied or you can compile them individually. All of the programs are one source file per executable file, except the main program citadel, which consists of: citadel.c messages.c rooms.c commands.c routines.c routines2.c This is also the only program that goes over 64k, so you'll need to compile it using a big memory model. File permissions are always a bother to work with. You don't want the board to crash because someone couldn't access a file, but you also don't want shell users peeking into the binaries to do things like reading others' mail, finding private rooms, etc. One solution is to make the data files accessible only by the super user, and setting the set-user-id bit for each program that accesses them. Sysop utilities should only be accessible by people in a given group, and the set-user-id bit should also be set. SETUP AND LOGIN You may now run the setup program, which will prompt you regarding whether it should create certain files. If this is the first time setting up the BBS, you will want to answer yes to all of the prompts. It will display what it is doing as it creates the various files needed to run the system. At this point, your system is ready to run. Run the citadel program from the shell and it will automatically create your account. You'll probably want to log right back out so you can give yourself aide access before continuing. THE PEANUT GALLERY That's just about all the information you need to install the system. If you have any comments, suggestions, bomb threats, etc., send them to UNCENSORED! BBS at (914) 761-6877. SHAR_EOF fi echo shar: "extracting 'netrelease.doc'" '(2893 characters)' if test -f 'netrelease.doc' then echo shar: "will not over-write existing file 'netrelease.doc'" else cat << \SHAR_EOF > 'netrelease.doc' This document is intended for Citadel/UX sysops who have a version of netproc lower than 1.5 and intend to modify the system to the latest networking standards INSTEAD of upgrading to Citadel/UX 3.00 and Network 1.5. If you are installing Citadel/UX 3.00 and Network 1.5, ignore this document. INFORMATION ON UPGRADING TO CITADEL/UX NETWORK PROTOCOL VERSION 1.5 ------------------------------------------------------------------- 1. MESSAGE ROUTING When netproc receives a message containing a "D" (destination system) field, and the destination system is not your system, ship off the message in the direction of that system. Netproc 1.5 looks at the network/mail.sysinfo file to determine which neighbor to send the message to in order for it to arrive on the destination system. If the "D" field is not present, or the destination system is your own, process the message. 2. RECEIVING BINARY MAIL When processing messages, if a message is received that has an "R" (recipient) field, search for that user and place the message in his/her mailbox. If the user does not exist, either return the message or alert the local management. Netproc 1.5 dumps undeliverable mail in the Aide> room. 3. SENDING BINARY MAIL Users should be able to go to the Mail> room and enter a recipient in the form of "user @ sysname". The message generated will contain the following fields: P - Sender's name, lower case, spaces replaced by underscores T - Date & time of message (standard Unix format) A - Sender's name O - Name of mail room N - Name of your system R - Name of recipient at destination system D - Name of destination system If the destination system is not a neigbor of your system, check the network/mail.sysinfo file to determine which of your neighbors it should be routed to. 4. NETPROC 1.5 New features supported: - Message routing using "D" field - Receiving binary mail. finduser() is used to locate a user in the usersupp file. This routine utilizes a binary search and assumes that the file is in alphabetical order. It returns the position of the correct usersupp record or (-1L) for User Not Found. If you are using a version earlier than 2.22, you must change finduser() to search using the conventional method. 5. CITADEL/UX 3.00 Too many changes have been made to the main program to make the binary mail sender part of the new network release. In particular, the routine to enter messages is no longer part of the main() loop. This was done in part to be able to use the program netmailer.c, which replaces uucitamail.c. The system will continue to support the sending of standard UUCP mail. 6. THE PEANUT GALLERY Questions, comments, suggestions, etc. should be directed to me at UNCENSORED! BBS (914) 761-6877 300/1200/2400. SHAR_EOF fi echo shar: "extracting 'network.doc'" '(8886 characters)' if test -f 'network.doc' then echo shar: "will not over-write existing file 'network.doc'" else cat << \SHAR_EOF > 'network.doc' Citadel/UX Network v1.5 Manual Written by Art Cancro [Inspector Gadget @ UNCENSORED! (914) 761-6877] See copyright.doc for copyright information OVERVIEW The fundamental structure of the networker is fairly simple, however, it has enough features to make it a bit complicated. This is probably the most difficult part of the entire Citadel/UX package. So before we dive in head first, let's look at the various network files and directories. netsetup.c Setup program for the networker. netproc.c Does all of the actual network processing. rnews.c Feeds standard input into the networker, also has the ability to translate UseNet news format into Citadel/UX binary format. netmailer.c Called by the main program when a user sends a network mail message. rmail.c A patch to allow Citadel/UX users to receive mail through the normal UUCP mail facility. cux2ascii.c A filter which translates Citade/UX binary format to UseNet news format. network Directory in which all network files reside. network/systems Contains network info for each neighboring system network/systems/sysname Network file for a node called "sysname". network/mail.aliases Aliases for the mailer. network/rnews.xref Cross-references room names to newsgroup names. network/prevmsgs The current use table. network/prevmsgs.pos Current file position in the use table. network/mail.sysinfo Contains routing information for network mail. SETUP There are two options in sysconfig.h which must be properly set. The first is NODENAME, which must be the same as your uucp system name. The other is PREVMSGS, which is the number of records in the use table (prevmsgs). The use table records the message number and origin of messages recently received over the network, to prevent the same message arriving from multiple sources to be posted twice. A good value to start with is about a thousand. NOTE: the value of PREVMSGS times the size of a record in the table (currently 14) must not exceed the maximum size of an array on your system. The entire table is read into an array in memory during inbound processing. Once you have edited sysconfig.h, compile and run the netsetup program. It will ask you if you want to clear the use table; answer yes. It will create network/prevmsgs and network/prevmsgs.pos, files that you will never have to deal with yourself (netproc handles them completely). SETTING UP SYSTEMS FILES For each of your neighboring Citadel/UX systems you must create a systems file. The file is called network/systems/sysname, where sysname is the other system's node name. The first line contains a command that transfers a spool file to the network/spoolin directory on the remote system. The string "%s" will be replaced by the name of the spool file by netproc. You may only use %s ONCE in the command line. Usually, some sort of UUCP transfer will be used to do the transfer, but you may use any facility you want, *** as long as the file ends up in the network/spoolin directory on the remote system ***. In a typical system, you will probably use uux to pipe the file through the command "rnews -c" on the remote system. When the remote system receives this command, it will copy standard input to the network/spoolin directory, and then begin processing the file as soon as it is there. After the command line you should enter the names of all the rooms you intend to share with this system. Each room name should be followed by a line containing a zero - this extra field is the "last message sent" (which will be updated by netproc when it is run). Here is a sample systems file for a node called uncnsrd: cat %s |uux - uncnsrd!rnews -c Network Test 0 Gateway 0 The Room 0 The rooms "Network Test", "Gateway", and "The Room" will be spooled to the remote system. These rooms should be designated as network rooms with the .<A>ide <E>ditRoom command. USING NETPROC Calling netproc with no arguments simply looks in the network/spoolin directory for newly arrived messages, and posts them if it finds any. If any message has already arrived on the system (which can happen in densely connected networks), they will be rejected. To collect new messages and send them off to a remote system, the usage netproc sysname will do outbound network processing for system "sysname". It is reccomended that you use the cron program to handle your network processing on a routine basis automatically. NETWORKING WITH A USENET NEWS SITE Two filters are provided that will allow a room to be equivalent to a UseNet newsgroup. rnews, when called without the -c argument, will assume that standard input is in the news format, and convert it before processing. Likewise, the filter cux2ascii.c converts Citadel format to news format, allowing you to use command lines such as cat %s |cux2ascii |uux - uunet!rnews ...the remote system need not be a Citadel/UX. By default, room names are the same as the newsgroup names. However, if you wish the room name to be different, you may specify so in the network/rnews.xref file. Here is a sample of this file: comp.unix.wizards,UNIX wizards alt.drugs,Drugs and Narcotics alt.music,Music It is rather simple, each line taking the form of newsgroupname,sysname. There may not be any spaces in the newsgroup name, but there may be spaces in the corresponding room name. To allow Citadel/UX users to receive standard UUCP mail, you can install the rmail patch provided. Simply compile rmail.c, move your old rmail to rmail.real, and put the compiled rmail in its place. Make sure the setuid bit is set, just as it is in rmail.real. Users may then receive network mail. If there are any spaces in users' names, people sending them mail may simply replace them with underscores. Note that this patch will not disturb the normal functioning of the UUCP mail facility. Also, for Citadel to Citadel mail, use the regular net mailer (although you may have both installed simultaneously). MAIL ALIASES The file network/mail.aliases is a simple list of aliases for the various mailers to use. Each line takes the form alias,name Obviously, neither the alias nor the name can contain commas. The name may also be the system name "sysop", where messages sent to sysop will be posted in the Aide> room. CITADEL/UX NETWORK MAIL Citadel/UX now has the ability to transport mail in a simple and transparent fashion not unlike the way public messages are sent. Users may enter recipient names exactly as they appear on top of messages (i.e., user name @ system name). In addition, mail routing is provided, allowing users to send mail to systems which do not directly connect with their own. When entering a message in the Mail> room, a user may type a recipient name on the local system, or on a remote system. If the recipient is not local, citadel.c calls netmailer.c, which is a standalone program that handles network mail. The system will fork, allowing netmailer to run in the background while the user goes on to something else. Network mail needs to have the file network/mail.sysinfo to work with. There are two types of entries in this file. A "use" entry tells the system which neighbor to route a message through to get to a particular non-neighboring system. A "bin" entry tells the system that a particular neighbor supports net mail. Here is a sample network map, where our system is called "myself": _____testbbs / othersys ----- myself ----- thebox / \_______theirsys funboard In this example, our neighbors are "othersys" and "thebox". othersys also connects to funboard, and thebox connects to testbbs and theirsys. If everyone supports netmail, the network/mail.sysinfo file would look like this: funboard use othersys testbbs use thebox theirsys use thebox othersys bin Mail theirsys bin Mail The "bin" entries specify neighbors, whereas the "use" entries specify routing. This way, anyone can send mail to anyone else. CONCLUSION That should cover everything you need to get running. By the way, a program to network with StoneHenge systems is available by special request. As always, comments and suggestions may be directed to UNCENSORED! BBS at (914) 761-6877. SHAR_EOF fi echo shar: "extracting 'sysop.doc'" '(7640 characters)' if test -f 'sysop.doc' then echo shar: "will not over-write existing file 'sysop.doc'" else cat << \SHAR_EOF > 'sysop.doc' Citadel/UX Sysop/Aide Manual Written by Art Cancro [Inspector Gadget @ UNCENSORED! (914) 761-6877] See copyright.doc for copyright information OVERVIEW Citadel/UX, when installed properly, will do most of its maintenance by itself. The message file loops upon itself forever, scrolling off old messages to make space for new ones. The room files work in the same way. Other types of maintenance can be done by cron. I have left my system unattended for long periods of time without any software failures. The system has five access levels. Most users are at the bottom and have no special privileges. Aides are selected people who have special access within the Citadel program. Room Aides only have this access in a certain room. Preferred users can be selected by Aides for access to preferred only rooms. A sysop is anyone who has access to the various sysop utilities - these are in their own executable files, which should have their permissions set to allow only sysops to run them. I reccomend either creating a sysops group in /etc/group, or using the "sys" group for this purpose. Aides have access to EVERY room on the system, public and private (all types). They also have access to commands starting with .<A>ide in addition to being able to delete and move messages. The system room, Aide>, iS accessible only by those designated by aides. AIDE COMMANDS Aides have the following commands available to them that are not available to normal users. They are: .<A>ide <E>dit room Allows an aide to change certain parameters of the current room. Lobby>, Mail>, and Aide> may not be edited. .<A>ide <K>ill room Deletes the current room. Lobby>, Mail>, and Aide> may not be deleted. .<A>ide <R>oom <I>nvite Invites a user to the room if it is private. .<A>ide <R>oom <K>ickOut Kicks a user out of the room if it is private. .<A>ide <U>serEdit Edits certain parameters of a user's account. .<A>ide <W>hoKnowsRoom Lists all users who have access to, and who have not chosen to zap, the current room. EDITING ROOMS This command allows and aide to change certain parameters of the current room. The current room name will be displayed, and then prompted: New name <return=same>? If you press return, the room name will remain unchanged. If you enter a new name, enter it exactly as you want it to appear. No case conversion will be done, unlike the .<E>nter <R>oom command. At this point, all of the room's parameters will be changed. Then the following prompts will appear: New room type? <1>pub <2>guessname <3>passwd <4>inv-only : Entering <1> will give all users access to the room. Entering <2> will only give access to those users who specifically type .<G>oto roomname. Until then, it will not appear in their <K>nown rooms list and it will not be included in their <G>oto loop. Entering <3> will prompt you for a room password. For users to access a passworded room, they must know the name AND password. Entering <4> will provide no means for users to access the room unless an aide invites them with the .<A>ide <R>oom <I>nvite user command. Preferred users only? Answering <Y>es will only allow "preferred users" access to the room. Note that the room should be public unless you wish to restrict access even further. Directory room? Answering <Y>es will make the room a "directory room" which can be used for uploads and downloads. If you answer <Y>es, you will also receive the following three prompts: Directory name? Enter the name of the subdirectory for this room's files (it will be in the u/d area of the bbs, i.e. if Citadel is in /usr/bbs and you enter "text", the room's u/d's will be in /usr/bbs/files/text). Uploading allowed? Answering <Y>es will allow users to upload into the room. Downloading allowed? Answering <Y>es will allow users to download from the room. Visible Directory? Answering <Y>es will allow users to read the file directory of the room. Network Room? The networker will access any room regardless of this flag. However, if you are on a network you should answer <Y>es for networked rooms for two purposes: first, to make Citadel/UX print the name of the originating system in the header of each message, and secondly, to make message entry in the room inaccessible to those users from whom you have revoked network privileges. <1>Normal <2>Anon-only <3>Anon-option ? Entering <1> will cause all messgaes in the room to have normal headers. Entering <2> will cause all message headers to read "****" Entering <3> will cause messages to have either normal headers or headers that read "<anonymous>", upon each user's choice during message entry. The current room aide's name will be displayed if there is one, and then you will be prompted: Room aide (RETURN to leave unchanged): Enter the new room aide's name, or press return to leave it unchanged. EDITING USERS This command allows and aide to change certain parameters of any user's account. Entering this command will ask for the name of a user to edit, and then present the following three prompts: Problem user (y/n)? Answering <Y>es will flag the person as a "problem user" - if TWITDETECT is enabled, ALL of this user's messages will automatically be moved into the problem users room. Deny network privs (y/n)? Answering <Y>es will prevent the user from entering messages in network rooms. Permanent user (never scroll off)? Answering <Y>es will prevent the user from being purged off the userlist by the sysoputil program. Preferred user (y/n)? Answering <Y>es will give the user "preferred user" status. DELETING AND MOVING MESSAGES Aides have the ability to delete and move messages; however, they must have message prompting turned on in order to do this. After each message, the normal prompt appears: <A>gain, <N>ext message, <S>top -> Entering <D> will delete the message. A (y/n) prompt will appear to confirm that you really want to delete the message. Entering <M> will prompt for a room to move the message to. SYSOP UTILITIES There are a number of utilities which may be accessed from the shell. It is up to the system operator to decide which should be "sysop" utilities and which should be accessible to all shell users. Please see utils.doc for a description of these programs. CONCLUSION Comments from the Peanut Gallery should be directed to (at) my humble mailbox at UNCENSORED! BBS (914) 761-6877. SHAR_EOF fi echo shar: "extracting 'utils.doc'" '(9231 characters)' if test -f 'utils.doc' then echo shar: "will not over-write existing file 'utils.doc'" else cat << \SHAR_EOF > 'utils.doc' Citadel/UX Utilities Manual Written by Art Cancro [Inspector Gadget @ UNCENSORED! (914) 761-6877] See copyright.doc for copyright information OVERVIEW The following utilities will be discussed in this document: aidepost Post standard input to the Aide> room. NOTE: called by chat.c whobbs Who is on the system, includes BBS names. NOTE: called by citadel.c msgstats Print lowest & highest message numbers, and current file position stats Print the calling statistics & graph. NOTE: requires "curses" rdml Read a user's mail msgform Format a binary message to the screen (stdin or in a file) userlist Print the userlist. NOTE: called by citadel.c (.RU option) readlog Read the caller log useradmin Full-screen user account editor. NOTE: requires the "curses" lib sysoputil Various and sundry sysop utilities. It is up to you to decide which utilities should be made accessible only to sysops. It is important that you set the file permissions correctly. All utilities should have access to the BBS data files, whether through ownership or set-user-id. In addition, aidepost should be accessible by the chat program, and userlist & whobbs should be accessible by citadel. I will attempt to address each program individually. AIDEPOST The nature of this program is rather simple. Standard input (stdin) is converted into a message, filed in the main message file (msgmain), and posted in the Aide> room. This is useful for keeping transcripts of system activity that has to do with the BBS. You may also wish to have a really BIG msgmain file, and have all of your normal system logs go in there also. The chat program included with Citadel, chat.c, uses this program to post a transcript of each chat that takes place. WHOBBS This is a simple replacement for the standard "who" command. It looks in /etc/utmp for users currently logged in. Instead of printing login names, it prints full names (i.e., the fifth field in /etc/passwd). If a logged in user's id happens to be BBSUID (the user is a BBS-only user), whobbs instead looks in the "utmpsupp" file for the name they are using under Citadel. Citadel/UX calls this program when any user types the <W>ho command. MSGSTATS This program displays the lowest and highest message numbers which currently exist in the master file, the current file pointer (what byte in msgmain the next message entered will start at), and whether the file is locked or unlocked. Normally the file will only be locked for a second or two during a message <S>ave, or network processing, but if there is a glitch somewhere and the file remains locked, this program will tell you so and you can use the unlock option in sysoputil. STATS This program is one of two which utilize the "curses" library. It prints various statistics on the screen based on the calllog file, such as number of calls, number of calls with certain baud rates, number of carrier drops, bad password attempts, etc. All statistics are provided in three figures: times per call, times per day, and total times. After this screen appears, you may press return for the next screen. This is a graphic representation of system usage. For each half hour segment of time during the day, it will display the average percentage of that segment which is used. Local logins are not included in this display. (As distributed, a "remote" login is considered anything at 300, 1200, or 2400 baud. You may wish to modify the code to decide just what really is "remote" on your particular system.) RDML This is a simple program to read any user's mail. This, of course, is unethical. It will prompt for a user name, after which it will display the user's mail. MSGFORM On occasion, I have had messages in Citadel/UX binary format that I have wanted to view. Or needed a way to view a network spool file. Or wanted to directly examine parts of msgmain. This program is a simple message formatter. Called without arguments, msgform will look for binary messages, starting with an <FF> byte and ending after the final NULL, and print as many as it finds until it encounters EOF. Called with one argument (msgform filename), msgform will display all messages found in "filename" from beginning to end. Called with two arguments (msgform filename startpos), msgform will display all messages found in filename starting at byte position "startpos". USERLIST This is a program to print the userlist. There are two flags that may be set when running this program. When called without any arguments, userlist will display all users (except those who have chosen to be unlisted), their user numbers, times called, messages posted, screen width, and date of their most recent call. Setting the -p option (only allowed by root as distributed; you may wish to change this) also displays passwords, and lists all users regardless of whether they are unlisted. Setting the -n option causes the next argument after -n to be a user number to search for. The Citadel/UX program calls userlist without any arguments for the .<R>ead <U>serlist option. READLOG Called without any arguments, readlog dumps the contents of the calllog file. This file records all times the Citadel/UX program has been started, and at what baud rate, as well as logins, proper logouts, loss of carrier (SIGHUP), bad password attempts, and new user logins. Readlog called with the -t argument displays a list of the names of the last twenty users who have logged in. USERADMIN Useradmin is a full-screen program to view and edit any user's account. The program will prompt for a user name. After you enter the name, various parameters of the user's account will appear on the screen. To change one of the parameters, simply enter its number. 1. User Name - it is ok to change the casing of a user's name, but if you change the name entirely, the userlist will no longer be in alphabetical order, which would cause problems in the Citadel program. 2. User number - if you change a user's number, keep in mind that the user's account will no longer be attached to any other records which are indexed by user number, such as the registration. 3. UID attachment - if you wish to attach a BBS account to an /etc/passwd account, simply make the uid's the same. Likewise, if a user is to no longer have an account in /etc/passwd, simply set this to the same as BBSUID. 4. Password - These 5. Screen width are 6. Times called self 7. Messages posted explanatory. 8. Last call - Time of last call (in unix format). If you select this, it will not prompt for a new time, but set it to the current time. The rest are boolean flags. Selecting them will toggle the options. 10. Aide privileges 11. Permanent user (do not scroll off) 12. Print last old message on new message request 13. Expert mode (supress automatic hints) 14. Do not list in .RU command 15. Prompting after each message 16. Problem user flag 17. Network privileges 18. Registered in the registration file 19. Preferred user In addition, if the user is registered, you can type -1 to make the corresponding record in the registration file appear on the screen. When you are finished examining or editing an account, type 0 to exit. It will ask you if you wish to save the changes. SYSOPUTIL This program handles some of the sysop functions of the system. It can be called three ways: sysoputil by itself brings up the menu. Also: sysoputil -u Execute option 7 (user purge) and exit sysoputil -r Execute option 1 (room purge) and exit sysoputil -g Execute option 2 (registration list) and exit The menu choices are as follows: 1. Purge old rooms. This will delete any rooms which have not been written to (posted in) in two weeks. Notification of purged rooms is posted in the Aide> room (using the aidepost utility). 2. Read registration file. This will partially list the registration file to the screen (partially: street address is omitted). 3. Delete a user. (self explanatory) 4. Unlock message file. The msgmain file is locked during message saves to prevent two users from writing to the file at once. If there is some sort of crash or bug and it remains locked, this will unlock it. 5. (future use) 6. Sort the userlog. If for some reason the userlog is not in alphabetical order, this will sort it. New users are alphabetically added into the log correctly, so there should normally be no reason to run this option. 7. Purge old users. This will delete any users which have not called in two months. Notification of purged users is posted in the Aide> room (using the aidepost utility). 8. Change casing of a user's name. Upper/lower case may be changed, but you may not change the name entirely as this will cause the file to no longer be in alphabetical order. 9. Quit That should cover all of the included utilities. Comments, suggestions, etc. should be directed to UNCENSORED! BBS (914) 761-6877. SHAR_EOF fi echo shar: "extracting 'readme.301.doc'" '(298 characters)' if test -f 'readme.301.doc' then echo shar: "will not over-write existing file 'readme.301.doc'" else cat << \SHAR_EOF > 'readme.301.doc' IMPORTANT MESSAGES FOR USERS UPGRADING FROM 3.00 TO 3.01 The format of the usersupp file has changed slightly. If you are upgrading, please obtain the 3.00-->3.01 migrate utility from UNCENSORED BBS at (914) 761-6877. The various access bits in the file have been changed to user levels. SHAR_EOF fi echo shar: "done with directory 'docs'" cd .. exit 0 # End of shell archive -- Some do, some don't. | eric@sactoh0.SAC.CA.US Some will, some won't. | ames!pacbell!sactoh0!eric I might! | ucbvax!csusac!sactoh0!eric | ( A Home For Unwanted 3B's )