agetty, alternative SYSV getty program (beta)

Wietse Z. Venema wietse at wzv.win.tue.nl
Thu Nov 30 09:48:38 AEST 1989


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 <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README agetty.c agetty.8 Makefile
# Wrapped by wietse at wzv on Wed Nov 29 22:42:22 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(490 characters\)
sed "s/^X//" >'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 at 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: "<junk><speed><junk>".
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 at 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 <stdio.h>
X#include <termio.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <varargs.h>
X#include <ctype.h>
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     * <junk><number><junk>
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: "<junk><speed><junk>".
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 at 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



More information about the Alt.sources mailing list