GETTY-PS - UUGETTY Theory of Operation --------------------------------------- OVERVIEW This document is intended to explain the interaction of uugetty and the Operating System, including the UUCP package, with particular focus on the lock files (which *must* be done right to get a modem port to do both dial-in and dial-out). The following bugs that apply to uugetty have been fixed: * INIT will not disable the port for 5 minutes if there is a problem opening the port for initialization; * WAITCHAR now works again; this allows UUGETTY to properly interact with UUCP (this feature was inadvertantly disabled in 2.0.7i); The following features that apply to uugetty have been added: * the ability to use UUGETTY and UUCP for both dial-in and dial-out, without the "alternate port"; * support for efax-0.9[a]; * 1200 baud has been added back in as a valid speed (in case anyone needs a *real* fallback rate!) CONTENTS 1. UUGETTY operation 2. GETTY operation 3. Interaction between UUGETTY and UUCP 4. Interaction between UUGETTY and efax 5. Troubleshooting 6. Credits, Thanks, Etc... 1. UUGETTY operation The basic idea behind Linux serial drivers is that dial-in (callin) and dial-out (callout) devices should not try to use the same port at the same time. In the far past, this was accomplished by juggling lockfiles (A "lockfile" is a file that tells all programs, except the one that created it, that the resource controlled by the lockfile is not available. Hence, if the file does not exist, the resource is not locked!). More reciently, the problem was taken care of in the kernel. Instead of one modem device, there were two: a dial-in device, named /dev/ttyS# (where # is the port number), and a dial-out device, named /dev/cua# (again, where # is the port number). The callin devices were used by programs like getty and uugetty; the callout devices were used by programs like UUCP, Seyon, and Kermit. If you are really interested, you can consult the Linux Device List for more information about these /dev entries. For reasons that are are not within the scope of this document, the "cua#" devices have fallen out of favor, and the ttyS# devices are now the accepted standard. (If you are interested, you can read a little about it in "Serial-HOWTO" and "Modem-HOWTO".) Starting in kernels 2.2, if you try to access any of the "cua#" ports (even just opening them), a message appears on the system console warning you that these ports are obsolete, and the corresponding ttyS# port should be used. The "fix" to this problem is to go back to using a single port, which may be viewed as "taking a giant leap backward" but really isn't. The two-devices for one port scheme was really kludgy, and a single-device approach really is simpler. It's just that there weren't standards for serial ports in those days, and the technology of the day didn't provide the tools to do the single-device job the right way. Those tools are now available, so let's update our approach to the problem! There are 2 key issues that need to be addressed to make the single-device approach work: 1. The lock files *must* be properly maintained; 2. The device must able to be opened when the modem-control signals (like DCD) are not asserted. Lockfile code has much improved since the "early days" - the newer routines now store the PID of the creating process, so that any subsequent process that wants to use the locked resource can verify that the process that locked the resource is still around. If it isn't then the current process can remove the lockfile and proceed without risking any confusion. Any programs that want to use a "shared" dial-in/dial-out modem must use these new routines. The UUCP and UUGETTY packages both use the newer routines, so that is not a problem. As for opening the port when the modem control signals are not asserted, the /dev/ttyS# device 'blocks' on open, by default. This means that the program will be stopped until the device is clear to open. For the device to be clear, two things must be true: no other process can be using the /dev/ttyS# device, and the carrier detect (DCD) signal of the serial port must be high. While the device is blocking, it is not busy, so dial-out devices can use the line. In other words, if uugetty is running on /dev/ttyS#, as long as no incoming calls open the line (causing the DCD signal go high), other programs are free to use the line. Blocking can be disabled by setting the O_NDELAY flag to the open system call. In this case, carrier detect is not needed to open the line; however, if /dev/ttyS# is busy, EBUSY is still returned in errno and the open fails. Finally, a blocking open will return EAGAIN in errno if another process closes the corresponding callout device. This allows uugetty to easily monitor the serial port, and reinitialize if another program might have changed serial port parameters (or modem parameters). When initializing the port, the device is opened with O_NDELAY by uugetty. This allows uugetty to check the port and not interfere with the lockfile mechanism. Uugetty only creates the lockfile just before prompting for the login name on the port. This, allows a window of opportunity to control creation of the lock file, and thereby allow both dial-in and dial-out from the same device. If no DCD signal is present, no login prompt is presented to the user, and therefore no lockfile is created, so the port is available for dial-out operations! If there are problems getting the DCD signal from the modem to the port accurately, you can always cross-wire the DTR signal from the port to the DCD signal on the port (as well as send the DTR signal to the modem!) and use the WAITCHAR option. This is not a preferred solution, however, because when the user logs out using this configuration, the modem will not typically auto-disconnect the call, possibly leaving the line connected indefinately. This is a *big* security risk, because if the user was not careful, and did not log out completely (i.e., they "just hang up"), then anyone who connects to the modem will be logged into your system! No username or password required!! It should be noted that the ttyS# port *requires* a DCD and a CTS signal before communications can work, normally. You should therefore have a cable that is wired as follows for a uugetty to modem connection: Port Modem 1 --- GND 1 Note that if your serial port or your modem is wired "funny", you *may* need use DTE to 2 ------------- 2 DTE wiring instead of DTE to DCE wiring. If you don't understand this note, then you need 3 ------------- 3 to find someone who understands serial port wiring to help you. --- 4 4 --- | | Also note that pins 4 and 5 are shorted --- 5 5 --- together at each end. This will work, or you may wire pins 4 to 4 and pins 5 to 5, which 6 ------------- 6 will enable hardware flow-control. You must then enable hardware flow-control on the 7 ------------- 7 serial port (by adding CRTSCTS to the appropriate line in "gettydefs"), or the getty 8 ------------- 8 won't be able to initialize the port. 20 ------------ 20 Please note that uugetty should always be used on ports with modems - whether the modem is dial-in only, dial-out only, or dial-in/dial-out. There are 2 reasons for this. First, a dial-in modem can always be used as dial-out modem and vis-versa. By using uugetty, you have the option of easily adding the feature you don't currently use. Second, having uugetty (as opposed to getty) listed in the system logs makes any transactions that occur on modem lines stand out, which is usually a good thing from a security point of view. But, if you like being "contrary", you *can* use getty on a port with a modem for dial-in only operation. Obviously, you should *not* use getty on a dial-out or dial-in/dial-out modem, as there would be no mechanism to properly resource share. When using uugetty with a modem, after *years* of fiddling around, I have found it is best to configure the modem to use a fixed serial port speed, and have the 2 modems (yours and the remote one) figure out what speed they can talk. This makes configuring the port *really* simple - pick a fixed baud rate that will *force* your modem into ECC or MNP mode (usually, the highest rate it is rated for) and use that as a fixed baud rate - no muss, no fuss on the getty side of things. And lastly, if you are using UUCP as a communication link between two local machines (such as an "emergency" link in case the network goes down, or as a secure channel), then you should use uugetty *with* hardware flow-control. I have achieved speeds as high as 230k baud between machines in the same room, over a 20 foot long cable. Using hardware flow-control at these speeds is *highly* recommended, as software flow-control (x-on/x-off) can not stop the flow of characters within 1 character, like hardware flow-control. (At least on modern UART chips! ) 2. GETTY operation Getty works *exactly* like uugetty, except that it is a "hard-wired" *ONLY* kind of connection (and so lock files are not maintained) and the program name is "getty" instead of "uugetty" (which shows up in the system and debugging logs). However, the hardware requirements are the same (DCD needs to be asserted, unless CLOCAL is specified for the port in "gettydefs"; and CTS need to be asserted, if CRTSCTS is specified in "gettydefs"). Getty is usually used only for the system console and typical VDT access, where the users log in, and no outbound communication is initiated by the system. While most VDT's assert the DCD and CTS signals, most installation people deem it a waste of money to pay for cable that has these extra conductors in it. (Although, there are certain high-security situations where using these signals may make sense. But then, if the users would just follow the established security policies, the extra security at the hardware level would not be needed.) So, it is typical to use the correct values in "gettydefs" so these signals are not needed (See examples of this in "gettydefs" in the "Examples" directory). Alternatively, you may cross-wire the needed signals in the connector attached to the port, as follows: Port Modem 1 --- GND 1 Note that if your serial port or your VDT is wired "funny", you *may* need 2 ----\ /------ 2 to use DTE to DTE wiring instead of X DTE to DCE wiring. If you don't 3 ----/ \------ 3 understand this note, then you need to find someone who understands serial --- 4 4 port wiring to help you. | --- 5 5 7 ------------- 7 --- 8 8 | -- 20 20 3. Interaction between UUGETTY and UUCP Uugetty and the programs in the UUCP package (as well as efax) all use the same lockfile routines, so they are always consistent in their maintaining of the lockfiles. As for opening the port when the modem control signals are not asserted, by default, the /dev/ttyS# device 'blocks' on open. This means that the program will be stopped until the device is clear to open. For the device to be clear, two things must be true: no other process can be using the /dev/ttyS# device, and the carrier detect (DCD) signal of the serial port must be high. While the device is blocking, it is not busy, so dial-out devices can use the line. In other words, if getty is running on /dev/ttyS1, as long as no incoming calls open the line (causing the carrier to go high), other programs are free to use the line. Blocking can be disabled by setting the O_NDELAY flag to the open system call. In this case, carrier detect is not needed to open the line; however, if /dev/ttyS# is busy, EBUSY is still returned in errno and the open fails. Finally, a blocking open will return EAGAIN in errno if another process closes the corresponding callout device. This allows getty to easily monitor the serial port, and reinitialize if another program might have changed serial port parameters (or modem parameters). 4. Interaction between UUGETTY and efax Uugetty and the programs in the EFAX package all use the same lockfile routines, so they are always consistent in their maintaining of the lockfiles. Like with UUCP above, by default, the /dev/ttyS# device 'blocks' on open. And again, this means that the program will be stopped until the device is clear to open. All of this is just like UUCP, above. Where EFAX is different is in the permissions issues that need to be dealt with to make efax, uugetty and UUCP work together to share one or more fax/modem ports. (My appologies, but this section was cut short to make a deadline. It will be completed in the next release.) 5. TROUBLESHOOTING So, what could possibly go wrong? A. Check the ownership of the programs (cu, uucico, etc). If the programs opening the port are *not* owned by uucp (or root) or the "setuid" bit is not set, then the program will not have permission to open the port. The security is kept very tight, as access to the modem port is a way for an intruder to *really* cause havoc on your system! B. Check the gettydefs file If there are any wrong settings in "gettydefs", getty can do some *pretty* strange things. These include, but are not limited to, not allowing access (I mean not even a login prompt!) to serial port VDTs, or modems, or both. A *big* hint that you have a gettydefs settings problem is that you have changed it in the last 24 hours or so, and the system console *does* work, but serial VDT's and/or modems do not! It is for this reason that I *strongly* recommend that you install the getttdefs file that comes with this distribution (in "Examples") and *NOT* change any of the lines that are in there (because I have tested them, and they all WORK!), but add new lines as needed, and modify these new lines as needed. C. Check the setings in /etc/default/[uu]getty* The settings in these files will override any options set on the command line. (Which really makes sense, if you think about it - since you can *also* create a "/etc/default/getty.ttyS1", and have any port-specific parameters in it.) But, for you purists out there, if there is no /etc/default/[uu]getty* file(s) out there, then the command line parameters control everything. D. Did you remember to do an "init q" after making any changes in "/etc/inittab"? I have on *several* occasions forgotten about this, and spend needless time trying to find a non-existant problem! E. After you change something in one of the up to 3 supporting files (/etc/gettydefs, /etc/ttytype, /etc/default/[uu]getty*), did you cycle the login once to get it to read the new values? This one may catch a few of you beginners off guard - but if you think about it, it makes perfect sense. If a login prompt is being displayed on the screen, then getty has *already* read all the necessary files and has the appropriate values stored in it's variables. In order to get it to load the *new* values, you need to log in and log out again on the port in question, or force getty to restart by doing a timeout, or turning getty "off" in /etc/inittab, then doing an "init q", then turning it *on* again in /etc/inittab and doing an "init q" again! (My appologies, but this section was cut short to make a deadline. It will be completed in the next release.) 6. CREDITS, ETC... Special thanks to all of these people: Paul Sutcliffe ... original author Steve Robbins ... former maintanier of getty_ps I hope this clears up any confusion that you may have had about how uugetty works with modems in general and UUCP in particular. The information in this document is the summary of 10 years of working with UUCP and uugetty, with various modems along the way. If you find anything that is not clear, or some important point I've missed, please let me know. Good Luck. Christine Jamison getty-info@nwmagic.net