Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!hp4nl!eutrc3!wzv!wietse From: wietse@wzv.win.tue.nl (Wietse Z. Venema) Newsgroups: alt.sources Subject: agetty, alternative SYSV getty program (beta) Message-ID: <614@wzv.win.tue.nl> Date: 29 Nov 89 22:48:38 GMT Distribution: alt Organization: Eindhoven University of Technology, The Netherlands Lines: 887 Finally, I got bored enough with the SYSV getty program's insistance on the # and @ line-editing characters and wrote a replacement. This version does adapt to line-editing characters found in its input, various forms of parity (even, odd, none, space), and also has support for multi-speed Hayes modem clones. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' X@(#) README 1.1 11/26/89 22:04:59 X XThis is a SYSV getty replacement that adapts itself to parity bits, and Xto erase, kill and end-of-line characters found in its input. It also Xhas an optional facility do detect the baud rate of incoming calls from Xthe status messages produced by some multi-speed Hayes modem clones. XThis program is an adapted version of a getty I once wrote for a V7 UNIX Ximplementation; it does not use the /etc/gettydefs file. X X Wietse Venema (wietse@wzv.win.tue.nl) END_OF_FILE if test 490 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'agetty.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'agetty.c'\" else echo shar: Extracting \"'agetty.c'\" \(18328 characters\) sed "s/^X//" >'agetty.c' <<'END_OF_FILE' X/*++ X/* NAME X/* agetty 8 X/* SUMMARY X/* alternative System-V getty X/* SYNOPSIS X/* agetty [-a alternate_rates] [-h] [-m] [-t timeout] port baud_rate X/* DESCRIPTION X/* \fIagetty\fR is the program that normally starts a login session. X/* It opens a tty port, prompts for a login name and invokes the X/* /bin/login command. X/* X/* \fIagetty\fR has some useful features not present in the System X/* V Release 2 getty command: X/* .IP o X/* adapts the tty settings to parity bits and to X/* erase, kill and end-of-line characters found in its input. X/* .IP o X/* optionally recognizes the baud rate of incoming X/* calls from the status messages produced by some multi-speed Hayes (tm) X/* modem clones. X/* .PP X/* This program does not use the /etc/gettydefs file. X/* X/* Options: X/* .TP X/* -a alternate_rates X/* Initially the program uses the \fIbaud_rate\fR as specified. X/* Upon receipt of successive BREAK characters the program will step X/* through the \fIalternate_rates\fR, which should be specified as a X/* comma-separated list (preferably in decreasing order). After the X/* \fIalternate_rates\fR have been tried, \fIagetty\fR will try the X/* speed specified with the \fIbaud_rate\fR argument and so on. X/* .TP X/* -h X/* Do not hang up the line. Normally, \fIagetty\fR will lower X/* DTR for two seconds to force a modem to hang up (if the hangup X/* feature has been compiled into the program). X/* .TP X/* -m X/* Try to extract the baud rate of incoming calls from the status message X/* produced by some Hayes (tm) multi-speed modem clones. These usually X/* produce a status message of the form: "". X/* If no \fIspeed\fR is found within one second, the \fIbaud_rate\fR as X/* specified on the command line will be used. Since this will work X/* only on lightly-loaded systems, you will probably want to use this X/* feature in combination with the \fI-a\fR option. X/* .TP X/* -t timeout X/* Causes the program to terminate if no user name could be read X/* within \fItimeout\fR seconds. This is useful for dial-in lines. X/* EXAMPLES X/* For hard-wired lines: X /etc/agetty ttyM0 9600 X/* For dial-up lines with a 300/1200/2400 baud Hayes clone: X /etc/agetty -t60 -m -a1200,300 ttyM1 2400 X/* BUGS X/* The baud-rate detection code (the \fI-m\fR option) only works if X/* \fIagetty\fR is scheduled soon enough after completion of a dial-in X/* call (30 ms with modems that talk at 2400 baud). For robustness, always X/* use the \fI-m\fR option in combination with the \fI-a\fR option. X/* X/* Only supports 7-bit characters with even, odd, none and space X/* parity (parity bit always equal to zero). X/* The login prompt is always output with space parity. X/* DIAGNOSTICS X/* All diagnostics are written to the console. X/* X/* In particular, \fIagetty\fR will detect if it is asked to open X/* someting that is not a terminal. X/* AUTHOR(S) X/* W.Z. Venema X/* wietse@wzv.win.tue.nl X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sat Nov 25 22:51:05 MET 1989 X/* LAST MODIFICATION X/* 89/11/29 22:33:21 X/* VERSION/RELEASE X/* 1.16 X/*--*/ X X#include X#include X#include X#include X#include X#include X#include X X /* X * Things you may want to modify. HANGUP should be defined only of your tty X * driver is not capable of hanging up the modem (by briefly dropping DTR). X * If HANGUP is defined you probably cannot use the time-out feature. X */ X X#define LOGIN "\r\nlogin: " /* login prompt */ X X/* #define HANGUP /* enable hangup code */ X X/* Some shorthands for control characters */ X X#define CTL(x) (x ^ 0100) /* controllify */ X#define CR CTL('M') /* carriage return */ X#define NL CTL('J') /* linefeed */ X#define BS CTL('H') /* backspace */ X#define DEL CTL('?') /* delete */ X X/* Default values of special characters; you may want to change this */ X X#define DEF_INTR CTL('C') /* default interrupt character */ X#define DEF_QUIT CTL('\\') /* default quit character */ X#define DEF_KILL CTL('U') /* default kill character */ X#define DEF_EOF CTL('D') /* default EOF character */ X#define DEF_SWITCH CTL('^') /* default switch character */ X#define DEF_ERASE BS /* default erase character */ X#define DEF_EOL 0 X X/* Storage for command-line options */ X X#define MAXSPEED 10 X Xstruct options { X int autobaud; /* process modem status messages */ X int timeout; /* timeout period */ X int hangup; /* hang up tty */ X int numspeed; /* number of baud rates to try */ X int curspeed; /* current speed */ X int speeds[MAXSPEED]; /* baud rates to be tried */ X char *tty; /* name of tty */ X}; X X/* Storage for things detected while the login name was read */ X Xstruct chardata { X int erase; /* erase character */ X int kill; /* kill character */ X int eol; /* end-of-line character */ X int parity; /* what parity did we see */ X int capslock; /* upper case without lower case */ X}; X X/* The following is used for understandable diagnostics */ X Xextern int errno; Xextern char *sys_errlist[]; Xstatic char *progname; Xextern char *strcpy(); Xextern char *strcat(); X X/* ... */ X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X char *logname; /* login name, given to /bin/login */ X char *get_logname(); X struct chardata chardata; /* set by get_logname() */ X struct termio termio; /* terminal mode bits */ X static struct options options = { X 0, /* no modem status message processing */ X 0, /* no timeout */ X 1, /* do hangup */ X 1, /* no baud-rate cycling */ X 0, /* use baud-rate argument as speed */ X }; X X progname = argv[0]; X X /* Parse command-line arguments */ X X parse_args(argc, argv, &options); X X /* Open the tty as standard { input, output, error } */ X X open_tty(options.tty, &termio); X X /* Optionally hang up the tty */ X X if (options.hangup) X hangup_tty(&termio); X X /* Initialize the termio settings (raw mode, eight-bit, blocking i/o) */ X X termio_init(&termio, options.speeds[0]); X X /* Optionally detect the baud rate from the modem status message */ X X if (options.autobaud) X auto_baud(&termio); X X /* Briefly pause, in order to allow modems or whatever to settle */ X X (void) sleep(1); X X /* Optional time-out feature */ X X if (options.timeout) X (void) alarm((unsigned) options.timeout); X X /* Read the login name */ X X while ((logname = get_logname(&options, &chardata)) == 0) X next_speed(&termio, &options); X X /* Disable time-out feature */ X X if (options.timeout) X (void) alarm(0); X X /* Finalize the termio settings */ X X termio_final(&termio, &chardata); X X /* Now the newline should be properly output */ X X (void) write(1, "\n", 1); X X /* Let /bin/login take care of password validation */ X X execl("/bin/login", "login", logname, (char *) 0); X error("%s: can't exec /bin/login: options.tty"); X /* NOTREACHED */ X} X X/* parse-args - parse command-line arguments */ X Xparse_args(argc, argv, op) Xint argc; Xchar **argv; Xstruct options *op; X{ X extern char *optarg; /* getopt */ X extern int optind; /* getopt */ X int c; X X while ((c = getopt(argc, argv, "a:hmt:")) != EOF) { X switch (c) { X case 'a': /* enable auto-baud feature */ X parse_speeds(op, optarg); X break; X case 'h': /* do not hangup the tty */ X op->hangup = 0; X break; X case 'm': /* parse modem status message */ X op->autobaud = 1; X break; X case 't': /* time out */ X if ((op->timeout = atoi(optarg)) <= 0) X error("bad timeout value: %s", optarg); X break; X case '?': X usage(); X } X } X if (argc != optind + 2) /* check parameter count */ X usage(); X op->tty = argv[optind++]; /* tty name */ X if ((op->speeds[0] = bcode(argv[optind])) <= 0) /* baud rate */ X error("bad speed: %s", argv[optind]); X} X X/* parse_speeds - parse alternate baud rates */ X Xparse_speeds(op, arg) Xstruct options *op; Xchar *arg; X{ X char *strtok(); X char *cp; X X for (cp = strtok(arg, ","); cp != 0; cp = strtok((char *) 0, ",")) { X if ((op->speeds[op->numspeed++] = bcode(cp)) <= 0) X error("bad speed: %s", cp); X if (op->numspeed > MAXSPEED) X error("too many alternate speeds"); X } X} X X/* open_tty - open tty as standard { input, output, error } */ X Xopen_tty(tty, tp) Xchar *tty; Xstruct termio *tp; X{ X struct stat st; X X /* Close standard { input, output, error } files, just in case */ X X (void) close(0); X (void) close(1); X (void) close(2); X errno = 0; /* ignore above errors */ X X /* Make sure we are given a character device */ X X if (chdir("/dev")) X error("/dev: chdir() failed"); X if (stat(tty, &st) < 0) X error("/dev/%s: stat() failed", tty); X if ((st.st_mode & S_IFMT) != S_IFCHR) X error("not a character device: /dev/%s", tty); X X /* Set up new standard input, output and error files */ X X if (open(tty, 2) != 0) /* set up std input */ X error("/dev/%s: cannot open as standard input", tty); X if (dup(0) != 1 || dup(0) != 2) /* set up std out and std err */ X error("%s: dup problem", tty); /* we have a problem */ X if (ioctl(0, TCGETA, tp) < 0) /* read tty status bits */ X error("%s: ioctl failed", tty); /* this is not a terminal */ X X /* It seems to be a terminal; set proper protections and ownership */ X X (void) chown(tty, 0, 0); /* root, sys */ X (void) chmod(tty, 0622); /* crw--w--w- */ X errno = 0; /* ignore above errors */ X} X X/* hangup_tty - hang up by forcing DTR down for at least 2 seconds */ X Xhangup_tty(tp) Xstruct termio *tp; X{ X#ifdef HANGUP X (void) signal(SIGHUP, SIG_IGN); X tp->c_cflag &= ~CBAUD; X tp->c_cflag |= B0; X (void) ioctl(0, TCSETA, tp); X (void) signal(SIGHUP, SIG_DFL); X (void) sleep(2); X#endif X} X X/* termio_init - initialize termio settings */ X Xtermio_init(tp, speed) Xstruct termio *tp; Xint speed; X{ X X /* X * Initial termio settings: 8-bit characters, raw-mode, blocking i/o. X * Special characters are set after we have read the login name; all X * reads will be done in raw mode anyway. X */ X X tp->c_cflag = CS8 | HUPCL | CREAD | speed; X tp->c_iflag = tp->c_lflag = tp->c_oflag = tp->c_line = 0; X tp->c_cc[VMIN] = 1; X tp->c_cc[VTIME] = 0; X (void) ioctl(0, TCSETA, tp); X} X X/* auto_baud - extract baud rate from modem status message */ X Xauto_baud(tp) Xstruct termio *tp; X{ X int speed; X int vmin; X int iflag; X char buf[BUFSIZ]; X char *bp; X int nread; X X /* X * This works only if the modem produces its status code AFTER raising X * the DCD line, and if the computer is fast enough to set the proper X * baud rate before the message has gone by. We expect a message of the X * following format: X * X * X * X * The number is interpreted as the baud rate of the incoming call. If the X * modem does not tell us the baud rate within one second we will keep X * using the current baud rate. It is advisable to enable baud-rate X * cycling (-a option) if the processing of modem status messages is X * enabled. X */ X X /* Use 7-bit characters, don't block if input queue is empty */ X X iflag = tp->c_iflag; X tp->c_iflag |= ISTRIP; /* enable 8th-bit stripping */ X vmin = tp->c_cc[VMIN]; X tp->c_cc[VMIN] = 0; /* don't block if queue empty */ X (void) ioctl(0, TCSETA, tp); X X /* X * Wait for a while, then read everything the modem has said so far and X * try to extract the speed of the dial-in call. X */ X X (void) sleep(1); X if ((nread = read(0, buf, sizeof(buf) - 1)) > 0) { X buf[nread] = '\0'; X for (bp = buf; bp < buf + nread; bp++) { X if (isascii(*bp) && isdigit(*bp)) { X if (speed = bcode(bp)) { X tp->c_cflag &= ~CBAUD; X tp->c_cflag |= speed; X } X break; X } X } X } X /* Restore settings */ X X tp->c_iflag = iflag; X tp->c_cc[VMIN] = vmin; X (void) ioctl(0, TCSETA, tp); X} X X/* next_speed - select next baud rate */ X Xnext_speed(tp, op) Xstruct termio *tp; Xstruct options *op; X{ X op->curspeed = (op->curspeed + 1) % op->numspeed; X tp->c_cflag &= ~CBAUD; X tp->c_cflag |= op->speeds[op->curspeed]; X (void) ioctl(0, TCSETA, tp); X} X X/* get_logname - get user name, establish parity, speed, erase, kill, eol */ X Xchar *get_logname(op, cp) Xstruct options *op; Xstruct chardata *cp; X{ X char logname[BUFSIZ]; X char *bp; X char c; /* input character, full eight bits */ X char ascval; /* low 7 bits of input character */ X int bits; /* # of "1" bits per character */ X int mask; /* mask with 1 bit up */ X static char *erase[] = { /* backspace-space-backspace */ X "\010\040\010", /* space parity */ X "\010\040\010", /* odd parity */ X "\210\240\210", /* even parity */ X "\210\240\210", /* no parity */ X }; X X /* Initialize kill, erase, parity etcetera (also after switching speeds) */ X X cp->kill = DEF_KILL; X cp->erase = DEF_ERASE; X cp->parity = 0; X X /* Read a login name */ X X for (*logname = 0; *logname == 0; /* void */ ) { X X /* Write the prompt, with "parity" bit == 0 */ X X (void) write(1, LOGIN, sizeof(LOGIN) - 1); X X /* Read name, watch for break, parity, erase, kill, end-of-line */ X X for (bp = logname, cp->eol = 0; cp->eol == 0; /* void */ ) { X if (read(0, &c, 1) < 1) X error("%s: read error", op->tty); X X /* Do BREAK handling elsewhere */ X X if ((c == 0) && op->numspeed > 1) X return (0); X X /* Do parity bit handling */ X X if (c != (ascval = (c & 0177))) { /* "parity" bit on ? */ X for (bits = 1, mask = 1; mask & 0177; mask <<= 1) X if (mask & ascval) X bits++; /* count "1" bits */ X cp->parity |= ((bits & 1) ? 1 : 2); X } X /* Do erase, kill and end-of-line processing */ X X switch (ascval) { X case CR: X case NL: X *bp = 0; /* terminate logname */ X cp->eol = ascval; /* send end-of-line char */ X break; X case BS: X case DEL: X case '#': X cp->erase = ascval; /* set erase character */ X if (bp > logname) { X (void) write(1, erase[cp->parity], 3); X bp--; X } X break; X case CTL('U'): X case '@': X cp->kill = ascval; /* set kill character */ X while (bp > logname) { X (void) write(1, erase[cp->parity], 3); X bp--; X } X break; X case CTL('D'): X exit(0); X default: X if (!isascii(ascval) || !isprint(ascval)) { X /* ignore garbage characters */ ; X } else if (bp - logname >= sizeof(logname) - 1) { X error("%s: input overrun", op->tty); X } else { X (void) write(1, &c, 1); /* echo the character */ X *bp++ = ascval; /* and store it */ X } X break; X } X } X } X cp->capslock = caps_lock(logname); /* upper case w/o lower case? */ X return (logname); X} X X/* termio_final - set the final tty mode bits */ X Xtermio_final(tp, cp) Xstruct termio *tp; Xstruct chardata *cp; X{ X /* General terminal-independent stuff */ X X tp->c_iflag |= IXON | IXOFF; /* 2-way flow control */ X tp->c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK; X tp->c_oflag |= OPOST; X tp->c_cc[VEOF] = DEF_EOF; X tp->c_cc[VEOL] = DEF_EOL; X tp->c_cc[VINTR] = DEF_INTR; X tp->c_cc[VQUIT] = DEF_QUIT; X tp->c_cc[VKILL] = DEF_KILL; X tp->c_cc[VERASE] = DEF_ERASE; X tp->c_cc[VSWTCH] = DEF_SWITCH; X X /* Account for special characters seen in input */ X X if (cp->eol == CR) { X tp->c_iflag |= ICRNL; /* map CR in input to NL */ X tp->c_oflag |= ONLCR; /* map NL in output to CR-NL */ X } X tp->c_cc[VERASE] = cp->erase; /* set erase character */ X tp->c_cc[VKILL] = cp->kill; /* set kill character */ X X /* Account for the presence or absence of parity bits in input */ X X switch (cp->parity) { X case 0: /* space (always 0) parity */ X break; X case 1: /* odd parity */ X tp->c_cflag |= PARODD; X /* FALLTHROUGH */ X case 2: /* even parity */ X tp->c_cflag |= PARENB; X tp->c_iflag |= INPCK | ISTRIP; X /* FALLTHROUGH */ X case (1 | 2): /* no parity bit */ X tp->c_cflag &= ~CSIZE; X tp->c_cflag |= CS7; X break; X } X /* Account for upper case without lower case */ X X if (cp->capslock) { X tp->c_iflag |= IUCLC; X tp->c_lflag |= XCASE; X tp->c_oflag |= OLCUC; X } X X /* Finally, make the new settings effective */ X X (void) ioctl(0, TCSETA, tp); X} X X/* caps_lock - string contains upper case without lower case */ X Xcaps_lock(s) Xchar *s; X{ X int hascaps; X X for (hascaps = 0; *s; s++) { X if (islower(*s)) X return (0); X if (hascaps == 0) X hascaps = isupper(*s); X } X return (hascaps); X} X X/* bcode - convert speed string to speed code; return 0 on failure */ X Xbcode(s) Xchar *s; X{ X struct Speedtab { X int speed; X int code; X }; X static struct Speedtab speedtab[] = { X 50, B50, X 75, B75, X 110, B110, X 134, B134, X 150, B150, X 200, B200, X 300, B300, X 600, B600, X 1200, B1200, X 1800, B1800, X 2400, B2400, X 4800, B4800, X 9600, B9600, X 19200, EXTA, X 0, 0, X }; X struct Speedtab *sp; X int speed = atoi(s); X X for (sp = speedtab; sp->speed; sp++) X if (sp->speed == speed) X return (sp->code); X return (0); X} X X/* usage - explain */ X Xusage() X{ X error("usage: %s [-a alternate_rates] [-h] [-m] [-t timeout] line baud_rate", X progname); X} X X/* error - report errors to the console; only understands %s */ X X#define str2cpy(b,s1,s2) strcat(strcpy(b,s1),s2) X X/* VARARGS */ X Xerror(va_alist) Xva_dcl X{ X va_list ap; X char *fmt; X int fd; X int err = errno; X char buf[BUFSIZ]; X char *bp; X X if ((fd = open("/dev/console", 1)) >= 0) { X (void) str2cpy(buf, progname, ": "); X bp = buf + strlen(buf); X X /* X * %s expansion is done by hand. The program would become three times X * as big if we would use the stdio library... X */ X X va_start(ap); X fmt = va_arg(ap, char *); X while (*fmt) { X if (strncmp(fmt, "%s", 2) == 0) { X (void) strcat(bp, va_arg(ap, char *)); X bp += strlen(bp); X fmt += 2; X } else { X *bp++ = *fmt++; X } X } X *bp = 0; X va_end(ap); X X /* Add system error message if errno was set */ X X if (err) X (void) str2cpy(bp, ": ", sys_errlist[errno]); X X /* Terminate with CR-LF since the console mode is unknown */ X X (void) strcat(bp, "\r\n"); X (void) write(fd, buf, strlen(buf)); X (void) close(fd); X } X (void) sleep(5); /* be kind to init */ X exit(1); X} X END_OF_FILE if test 18328 -ne `wc -c <'agetty.c'`; then echo shar: \"'agetty.c'\" unpacked with wrong size! fi # end of 'agetty.c' fi if test -f 'agetty.8' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'agetty.8'\" else echo shar: Extracting \"'agetty.8'\" \(3057 characters\) sed "s/^X//" >'agetty.8' <<'END_OF_FILE' X.TH AGETTY 8 X.ad X.fi X.SH NAME Xagetty X\- Xalternative System-V getty X.SH SYNOPSIS X.na X.nf Xagetty [-a alternate_rates] [-h] [-m] [-t timeout] port baud_rate X.SH DESCRIPTION X.ad X.fi X\fIagetty\fR is the program that normally starts a login session. XIt opens a tty port, prompts for a login name and invokes the X/bin/login command. X X\fIagetty\fR has some useful features not present in the System XV Release 2 getty command: X.IP o Xadapts the tty settings to parity bits and to Xerase, kill and end-of-line characters found in its input. X.IP o Xoptionally recognizes the baud rate of incoming Xcalls from the status messages produced by some multi-speed Hayes (tm) Xmodem clones. X.PP XThis program does not use the /etc/gettydefs file. X XOptions: X.TP X-a alternate_rates XInitially the program uses the \fIbaud_rate\fR as specified. XUpon receipt of successive BREAK characters the program will step Xthrough the \fIalternate_rates\fR, which should be specified as a Xcomma-separated list (preferably in decreasing order). After the X\fIalternate_rates\fR have been tried, \fIagetty\fR will try the Xspeed specified with the \fIbaud_rate\fR argument and so on. X.TP X-h XDo not hang up the line. Normally, \fIagetty\fR will lower XDTR for two seconds to force a modem to hang up (if the hangup Xfeature has been compiled into the program). X.TP X-m XTry to extract the baud rate of incoming calls from the status message Xproduced by some Hayes (tm) multi-speed modem clones. These usually Xproduce a status message of the form: "". XIf no \fIspeed\fR is found within one second, the \fIbaud_rate\fR as Xspecified on the command line will be used. Since this will work Xonly on lightly-loaded systems, you will probably want to use this Xfeature in combination with the \fI-a\fR option. X.TP X-t timeout XCauses the program to terminate if no user name could be read Xwithin \fItimeout\fR seconds. This is useful for dial-in lines. X.SH EXAMPLES X.na X.nf XFor hard-wired lines: X /etc/agetty ttyM0 9600 XFor dial-up lines with a 300/1200/2400 baud Hayes clone: X /etc/agetty -t60 -m -a1200,300 ttyM1 2400 X.SH BUGS X.ad X.fi XThe baud-rate detection code (the \fI-m\fR option) only works if X\fIagetty\fR is scheduled soon enough after completion of a dial-in Xcall (30 ms with modems that talk at 2400 baud). For robustness, always Xuse the \fI-m\fR option in combination with the \fI-a\fR option. X XOnly supports 7-bit characters with even, odd, none and space Xparity (parity bit always equal to zero). XThe login prompt is always output with space parity. X.SH DIAGNOSTICS X.ad X.fi XAll diagnostics are written to the console. X XIn particular, \fIagetty\fR will detect if it is asked to open Xsometing that is not a terminal. X.SH AUTHOR(S) X.na X.nf XW.Z. Venema Xwietse@wzv.win.tue.nl XEindhoven University of Technology XDepartment of Mathematics and Computer Science XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X.SH CREATION DATE X.na X.nf XSat Nov 25 22:51:05 MET 1989 X.SH LAST MODIFICATION X.na X.nf X89/11/29 22:33:21 X.SH VERSION/RELEASE X.na X.nf X1.16 END_OF_FILE if test 3057 -ne `wc -c <'agetty.8'`; then echo shar: \"'agetty.8'\" unpacked with wrong size! fi # end of 'agetty.8' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(257 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# @(#) Makefile 1.3 11/26/89 22:20:28 X XSHELL = /bin/sh XCFLAGS = -s -O XFILES = README agetty.c agetty.8 Makefile X Xagetty: agetty.c X cc $(CFLAGS) -o $@ $? X Xclean: X rm -f agetty.o agetty X Xshar: $(FILES) X @shar $(FILES) X Xagetty.8: X srctoman agetty.c >agetty.8 END_OF_FILE if test 257 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi echo shar: End of shell archive. exit 0 Brought to you by Super Global Mega Corp .com