|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 7854 (0x1eae)
Types: TextFile
Names: »main.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec8/uutty/main.c«
#include "uutty.h"
#include <signal.h>
static char id[] = "@(#)RELEASE: 1.0 Sep 20 1986 ~jc/uutty";
/*
** uutty device [option]...
**
** This is John Chambers' own personal serial-port daemon,
** to watch a port, determine what sort of critter is at the
** other end of the line, and engage it in a semi-intelligent
** dialog. The primary goal of this version, uutty, is to
** make it possible to use direct links (null modems) freely in
** both directions, without the problems caused by the getty(1)
** program. In particular, it allows the use of the uucp package
** (including uux and cu) in both directions across a line.
**
** Another thing uutty is good for is using a modem in either
** without needing any special actions.
**
** Uutty is a thinly-disguised "state machine" whose basic
** behavior is determined by a global "state variable" ss
** and a string of input characters. The state variable is
** simply an integer that encodes the last action performed.
** An input routine is called, and when it returns, the input
** is examined to determine the program's next action. Normally,
** this action is to produce an output string, change the state
** variable, and wait for the next input.
**
** The major intent of this program is to do a login interview,
** but to ignore anyone at the other end of the line that acts
** like it's trying to log us in. If getty or this program is
** at the other end, the result will be silence until someone
** sends a CR or LF (which elicits "login:") or something that
** is acceptable as a login id. Note in particular that input
** containing colons and spaces will be ignored.
**
** The other major intent is to cooperate with any software that
** sets the uucp lockfiles ("/usr/spool/uucp/LCK..<device>"), by
** checking for such lockfiles frequently, and sleeping any time
** they are found. This program never creates a lockfile; it just
** sleeps when someone else creates one. Thus, this program may
** be left running on a port used by uucp, cu, or other such serial-
** port users. There is a slight possibility that this program
** may eat up part of the first response from the port, but that
** is rarely much of a problem. One or two CRs will usually suffice
** to elicit a "gin:" prompt from the other end.
**
** A third, minor intent is to recognize overly-intelligent modems,
** and refuse to become engaged in a conversations with them. This
** is done primarily by rejecting input that contains whitespace or
** special characters, or which contains only upper-case letters.
** This will handle the error messages produced by most commercial
** modems. However, users may wish to add to the code that examines
** login ids and passwords, and add more checks for specific modems.
**
** You may notice that this program is full of Dx(...) debug calls.
** These are defined in dbg.h, and may be suppressed fairly easily.
** Most C compilers will react to, for instance:
** #define D9 if(0) dmsg
** by generating no code at all. You might think this would make
** your program smaller and faster, and you'd be partly right. It
** will definitely be smaller, but probably not much faster. Anyhow,
** the speed of this program isn't much of an issue; if it gets into
** a feedback loop with a modem, you don't much care how efficiently
** it brings your system to its knees! It's probably a wiser idea
** to leave most of the diagnostic junk in. You'll be surprised at
** how useful it can be to have that stuff in an audit trail.
**
** Some of the options recognized are:
**
** -b<n> use a baud rate of <n>. Final "00" may be omitted.
**
** -c<n> slow down by counting to <n> between output chunks.
**
** -d<n> debug level <n>; default is -d1.
**
** -e<s> exit string <s> to send when terminating.
**
** -f fork a subprocess for starting shells.
**
** -i<s> initialization string <s> is sent whenever it is
** decided that the other end is insane or jabbering.
**
** -l create uucp lockfiles before starting a shell; delete
** them afterwards. This option implies the -f option.
**
** -n<s> nudge string <s> is sent when this program wants a response.
**
** -p<f> port to use, where <f> is usually /dev/tty??. This is
** the same as using <f> without any prefix.
**
** -s<n> sleep <n> seconds between output chunks.
**
** -x<n> debug level <n>.
**
** To be responsible, I should repeat the warning stated elsewhere:
** with debug level -d2 or higher, uutty writes everything it sees,
** including unencrypted login ids and passwords, to its diagnostic
** output stream (audit trail). This makes it a Trojan Horse of the
** first kind. If you are security-conscious, you might take steps
** to hide the audit trail, and purge it frequently.
**
** In any case, the audit trail grows without bounds, so you will want
** to take steps to keep it within bounds. The easiest way is with an
** entry in crontab that starts up a daily cleanup script (/etc/cleanup
** is a real good name for it). This script can move the uutty audit
** trails to a different name, to produce one level of backup.
*/
main(ac,av)
char**av;
{ int i, r;
time(&currtime); /* Note the start time */
progname = av[0]; /* For debug output */
prgnam = lastfield(progname,'/');
D4("prgnam=\"%s\" progname=\"%s\"",prgnam,progname);
euid = geteuid();
egid = getegid();
ruid = getuid();
rgid = getgid();
D3("euid=%d egid=%d ruid=%d rgid=%d",euid,egid,ruid,rgid);
args(ac,av); /* Process command-line args */
if (debug) { /* Generate first entries in audit trail */
P("+--------------------------------------------------------------------+");
P("%s %s started.",getime(),progname);
}
timeout = 255; /* Use max timeout on reads */
sig(); /* Intercept all the signals */
slowfl = (count > 0) || (slow > 0);
opendev(); /* Open the port which we are to use */
if (dev != 0) {close(0); i = dup(dev); D3("File %d=\"%s\"",i,device);}
if (dev != 1) {close(1); i = dup(dev); D3("File %d=\"%s\"",i,device);}
lockwait(); /* First check to see if it's busy */
/*
** The code to handle raw, 8-bit communication get a bit weird from
** system to system. Here, we try to trap the initial state of the
** port, so that when we die, we can first restore it.
*/
#ifdef SYS5
if (raw && isatty(dev)) { /* We will want to restore its initial state */
D5("main:before ioctl(%d,%d,%06lX)",dev,TCGETA,&trminit);
i = ioctl(dev,TCGETA,&trminit); /* Note initial state of terminal */
D5("main: after ioctl(%d,%d,%06lX)=%d",dev,TCGETA,&trminit,i);
D7("main: %d:\tcflag=%06o",dev,trminit.c_cflag);
D7("main: %d:\tiflag=%06o",dev,trminit.c_iflag);
D7("main: %d:\tlflag=%06o",dev,trminit.c_lflag);
D7("main: %d:\toflag=%06o",dev,trminit.c_oflag);
termfl = 1;
/* crlf = "\n\r"; ** Not needed on Unix systems */
}
#endif
restdev(); /* Get port to desired (raw, very public) state */
#ifdef SYS5
/*
** The following functions suffice to find, update, and write
** the appropriate entry in the /etc/utmp file, which on SYS/V
** is the record of logged-in users. This may well have to be
** changed for other systems. The hope here is that this is a
** reasonable way to modularize the job, though the names may
** not be ideal...
*/
D8("main:before findutmp()");
up = findutmp(); /* Try to locate our /etc/utmp entry */
D7("main: after findutmp()=%06lX",up);
D8("main:before fillutmp(\"%s\",%X,\"%s\",%d)",prgnam,(char*)0,devfld,LOGIN_PROCESS);
fillutmp(prgnam,(char*)0,devfld,LOGIN_PROCESS);
D7("main: after fillutmp()");
D8("pswd:before pututline(%06lX)",up);
pututline(up); /* Put modified line into /etc/utmp */
D7("pswd: after pututline(%06lX)",up);
#endif
r = talk(); /* Attempt a conversation */
die(r); /* If we should ever decide to stop */
return 0; /* Paranoia! */
}