[alt.sources] Enhanced SYSV Getty, v1.1, part 3 of 4

paul@devon.lns.pa.us (Paul Sutcliffe Jr.) (01/17/90)

#! /bin/sh

# Make a new directory for the getty sources, cd to it, and run kits 1
# thru 4 through sh.  When all 4 kits have been run, read README.

echo "This is getty 1.1 kit 3 (of 4).  If kit 3 is complete, the line"
echo '"'"End of kit 3 (of 4)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
mkdir man 2>/dev/null
echo Extracting man/getty.m4
sed >man/getty.m4 <<'!STUFFY!FUNK!' -e 's/X//'
X.\" +----------
X.\" |	$Id: getty.m4,v 1.1 90/01/16 16:01:43 paul Exp Locker: paul $
X.\" |
X.\" |	GETTY/UUGETTY man page.
X.\" |
X.\" |	Copyright 1989,1990 by Paul Sutcliffe Jr.
X.\" |
X.\" |	Permission is hereby granted to copy, reproduce, redistribute,
X.\" |	or otherwise use this software as long as: there is no monetary
X.\" |	profit gained specifically from the use or reproduction or this
X.\" |	software, it is not sold, rented, traded or otherwise marketed,
X.\" |	and this copyright notice is included prominently in any copy
X.\" |	made.
X.\" |
X.\" |	The author make no claims as to the fitness or correctness of
X.\" |	this software for any use whatsoever, and it is provided as is. 
X.\" |	Any use of this software is at the user's own risk.
X.\" |
X.\"
X.\" +----------
X.\" |	$Log:	getty.m4,v $
X.\" |	Revision 1.1  90/01/16  16:01:43  paul
X.\" |	Initial revision
X.\" |	
X.\" |	
X.\" 
X.\" +----------
X.\" | M4 configuration
X.\"
Xinclude(config.m4).\"
X.\"
X.\" define(`_gtab_file_', _gtab_`_file')
X.\"
X.\" +----------
X.\" | Manpage source follows:
X.\"
X.TH GETTY _mcmd_section_ "DATE" "Release RELEASE"
X.SH NAME
Xgetty \- sets terminal mode, speed, and line discipline
X.SH SYNOPSIS
X.B /etc/getty
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
X.B speed
X.I [defaults_file],
X.\" | else (trs16)
X[\-d
X.I defaults_file]
X[\-h] [\-r
X.I delay]
X[\-t
X.I timeout]
X.B line
X.I [speed [type [lined]]])
X.\" | M4_end (trs16)
X.\" +----------
X.br
X.B /etc/getty \-c
X.I _gtab_file_
X.SH DESCRIPTION
X.I Getty
Xis the second of the three programs
X.I (init(_mcmd_section_), getty(_mcmd_section_),
Xand
X.I login(_mcmd_section_)),
Xused by the
X.\" +----------
X.\" | M4_start
Xifdef(`M_XENIX', XENIX, .\")
Xifdef(`XENIX', XENIX, .\")
Xifdef(`UNIX', UNIX, .\")
X.\" | M4_end
X.\" +----------
Xsystem to allow users to login.
X.I Getty
Xis invoked by
X.I init(_mcmd_section_)
Xto:
X.br
X.TP 3
X1.
XOpen tty lines and set their modes.
X.TP
X2.
XPrint the login prompt, and get the user's name.
X.TP
X3.
XInitiate a login process for the user.
X.P
XThe actual procedure that
X.I getty
Xfollows is described below:  Initially,
X.I getty
Xparses its command line.  If no errors are found,
X.I getty
Xscans the defaults file (normally
X.B _defaults_`/getty\fR)'
Xto determine certain runtime values.  The values in the defaults file
X(whose compiled\-in name can be altered with the optional
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16', .\", .B \-d)
X.\" | M4_end (trs16)
X.\" +----------
X.I defaults_file
Xargument) take precedence to those on the command line.
X.I Getty
Xthen opens the
X.I line
Xfor reading and writing, and disables stdio buffering.
X.\" +----------
X.\" | M4_start (logutmp)
Xifdef(`logutmp',
XThe
X.I utmp(_file_section_)
Xand
X.I wtmp(_file_section_)
Xfiles are updated to indicate a LOGIN_PROCESS.,
X.\" | else (logutmp)
X.\")
X.\" | M4_end (logutmp)
X.\" +----------
XIf an initialization was specified, it is performed (see LINE
XINITIALIZATION).
X.PP
XNext,
X.I getty
Xtypes the
X.\" +----------
X.\" | M4_start (issue)
Xifdef(`_issue_',
Xissue `(or login banner,' usually from
X.B _issue_`\fR)'
Xand,
X.\" | else (issue)
X.\")
X.\" | M4_end (issue)
X.\" +----------
Xlogin prompt.  Finally,
X.I getty
Xreads the user's login name and invokes
X.I login(_mcmd_section_)
Xwith the user's name as an argument.  While reading the name,
X.I getty
Xattempts to adapt the system to the speed of the terminal being used,
Xand also sets certain terminal parameters (see
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
X.I tty`('_misc_section_`))',
X.\" | else (trs16)
X.I termio`('_misc_section_`))')
X.\" | M4_end (trs16)
X.\" +----------
Xto conform with the user's login procedure.
X.PP
XThe tty device used by
X.I getty
Xis determined by
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
Xa call to
X.I ttyname(S)`,'
Xwhich sets the
X.I line
Xvalue.,
X.\" | else (trs16)
Xthe
X.I line
Xargument.)
X.\" | M4_end (trs16)
X.\" +----------
X.I Getty
Xuses the string
X.B /dev/\fIline\fR
Xas the name of the device to attach itself to.  Unless
X.I getty
Xis invoked with the
X.B \-h
Xflag (or
X.B HANGUP=NO
Xis specified in the defaults file), it will force a hangup on the line
Xby setting the speed to zero.  Giving
X.B \-r
X.I delay
Xon the command line (or using
X.B WAITCHAR=YES
Xand
X.B DELAY=\fIdelay\fR
Xin the defaults file) will cause
X.I getty
Xto wait for a character from the line, and then to wait
X.I delay
Xseconds before continuing.  If no delay is desired, use
X.B \-r0\fR.
XGiving
X.B \-t
X.I timeout
Xon the command line (or using
X.B TIMEOUT=\fItimeout\fR
Xin the defaults file) will cause
X.I getty
Xto exit if no user name is accepted within
X.I timeout
Xseconds after the login prompt is typed.
X.PP
XThe
X.I speed
Xargument is a label to a entry in the
X.B _gettytab_
Xfile (see
X.I _gtab_`('_file_section_)).
XThis entry defines to
X.I getty
Xthe initial speed (baud rate) and tty settings, the login prompt to be
Xused, the final speed and tty settings, and a pointer to another entry
Xto try should the user indicate that the speed is not correct.  This
Xis done by sending a
X.I <break>
Xcharacter (actually sequence).  Under certain conditions, a
Xcarriage\-return will perform the same function.  This is usually the
Xcase when getty is set to a higher speed than the modem or terminal.
X.I
XGetty
Xscans the
X_gtab_
Xfile sequentially looking for a matching entry.
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
XIf an entry for the given
X.I speed,
X.\" | else (trs16)
XIf no
X.I speed
Xwas given or the entry)
X.\" | M4_end (trs16)
X.\" +----------
Xcannot be found, the first entry in the
X.B _gettytab_
Xfile is used as a default.  In the event that the
X_gtab_
Xfile cannot be
Xaccessed`,' there is a compiled\-in default that is used.
X.PP
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
XThe terminal type is determined by examining the
X.I ttytype
Xfile`,' using the value associated with
X.I line.
X.I Getty
Xuses this value to determine how to clear the video display.,
X.\" | else (trs16)
XThe
X.I type
Xargument is a string which names the type of terminal attached to the
Xline.  The
X.I type
Xshould be a valid terminal name listed in the
X.\" +----------
X.\" | M4_start (termcap)
Xifdef(`termcap',
X.B termcap(_misc_section_),
X.\" | else (termcap)
X.B terminfo(_misc_section_))
X.\" | M4_end (termcap)
X.\" +----------
Xdatabase.
X.\" +----------
X.\" | M4_start (ttytype)
Xifdef(`ttytype',
XIf no
X.I type
Xis given on the command line`,' one is deduced from the
X.B ttytype
Xfile.,
X.\" | else (ttytype)
X.\")
X.\" | M4_end (ttytype)
X.\" +----------
X.I Getty
Xuses this value to determine how to clear the video display.
X.PP
XThe
X.I lined
Xargument is a string describing the line discipline to use on the
Xline.  The default is
X.B LDISC0\fR.)
X.\" | M4_end (trs16)
X.\" +----------
X.PP
XAs mentioned,
X.I getty
Xtypes the login prompt and then reads the user's login name.  If a
Xnull character is received, it is assumed to be the result of the user
Xpressing the
X.I <break>
Xkey or the carriage\-return key to indicate the speed is wrong.  This
Xcauses
X.I getty
Xto locate the next
X.I speed
Xin the series (defined in _gettytab_).
X.PP
XThe user's name is terminated by a new\-line or carriage\-return
Xcharacter.  A carriage\-return results in the system being set to map
Xthose to new\-lines (see
X.I ioctl(_system_section_)).
X.PP
XThe user's name is scanned to see if it contains only upper\-case
Xcharacters.  If so,
X.\" +----------
X.\" | M4_start (warncase)
Xifdef(`warncase',
Xa warning is issued to the user to retry his login`,' using lower\-case
Xif possible.  If the second attempt is still all upper\-case`,',
X.\" | else (warncase)
X.\")
X.\" | M4_end (warncase)
X.\" +----------
Xthe system is set to map any future upper\-case characters into
Xlower\-case.
X.PP
XA check option is provided for testing the
X_gtab_
Xfile.  When
X.I getty
Xis invoked with the
X.B \-c
X.I _gtab_
Xoption, it scans the named
X.I _gtab_
Xfile and prints out (to the standard output) the values it sees.  If
Xany parsing errors occur (due to errors in the syntax of the
X_gtab_
Xfile), they are reported.
X.SH "DEFAULTS FILE"
XDuring its startup,
X.I getty
Xlooks for the file
X.B _defaults_`/getty\fI.line\fR,'
X(or, if it cannot find that file, then
X.B _defaults_`/getty\fR),'
Xand if found, reads the contents for lines of the form
X
X.in +.5i
XNAME=\fIvalue\fR
X.in -.5i
X
XThis allows getty to have certain features configurable at runtime,
Xwithout recompiling.  The recognized NAME strings, and their
Xcorresponding values, follows:
X.TP 8
XSYSTEM=\fIname\fR
XSets the nodename value (displayed by
X.B @S
X\-\- see PROMPT SUBSTITUTIONS) to
X.I name.
XThe default is the
X.I nodename
Xvalue returned by the
X.I uname(_library_section_)
Xcall.  On XENIX systems, if the value of nodename is a zero\-length
Xstring, the file
X.B /etc/systemid
Xis examined to get the nodename.
XNote that some sites may have elected to compile the nodename value
Xinto
X.I getty.
X.TP
XVERSION=\fIstring\fR
XSets the value that is displayed by the
X.B @V
Xparameter (see PROMPT SUBSTITUTIONS) to
X.I string.
XThere is no default value.  If
X.I string
Xbegins with a '/' character, it is assumed to be the full pathname of a
Xfile, and
X.B @V
Xis set to the contents of that file.
X.TP
XLOGIN=\fIname\fR
XSets the name of the login program to
X.I name.
XThe default is
X.B _login_
X(see
X.I login(_mcmd_section_)).
XIf used,
X.I name
Xmust be the full pathname of the program that
X.I getty
Xwill execute instead of
X.B _login_\fR.
XNote that this program is called, as is
X.B _login_\fR,
Xthe with the user's name as its only argument.
X.TP
XINIT=\fIstring\fR
XIf defined,
X.I string
Xis a send/expect sequence that is used to initialize the line before
X.I getty
Xattempts to use it.  This string is in a form resembling that used by
Xthe
X.I L.sys
Xor
X.I Systems
Xfile of
X.I uucp(_cmd_section_).
XFor more details, see LINE INITIALIZATION.  By default, no
Xinitialization is done.
X.\" +----------
X.\" | M4_start (issue)
Xifdef(`_issue_',
X.TP
XISSUE=\fIstring\fR
XDuring startup`,'
X.I getty
Xdefaults to displaying`,' as an issue or login banner`,' the contents of
Xthe
X.B _issue_
Xfile.  If ISSUE is defined to a
X.I string`,'
Xthat string is typed instead.  If
X.I string
Xbegins with a '/' character`,' it is assumed to be the full pathname of
Xa file`,' and that file is used instead of
X.B _issue_\fR.,
X.\" | else (issue)
X.\")
X.\" | M4_end (issue)
X.\" +----------
X.TP
XCLEAR=\fIvalue\fR
XIf
X.I value
Xis
X.B NO\fR,
Xthen 
X.I getty
Xwill not attempt to clear the video screen before typing the
X.\" +----------
X.\" < M4_start (issue)
Xifdef(`_issue_',
Xissue or login prompts.,
X.\" | else (issue)
Xlogin prompt.)
X.\" | M4_end (issue)
X.\" +----------
X.TP
XHANGUP=\fIvalue\fR
XIf
X.I value
Xis
X.B NO\fR,
Xthen
X.I getty
Xwill NOT hangup the line during its startup.  This is analogus to
Xgiving the
X.B \-h
Xargument on the command line.
X.TP
XWAITCHAR=\fIvalue\fR
XIf
X.I value
Xis
X.B YES\fR,
Xthen
X.I getty
Xwill wait for a single character from it's line before continuing.
XThis is useful for modem connections where the modem has CD forced
Xhigh at all times, to keep getty from endlessly chatting with the
Xmodem.
X.TP
XDELAY=\fIseconds\fR
XUsed in conjunction with
X.B WAITCHAR\fR,
Xthis adds a time delay of
X.I seconds
Xafter the character is accepted before allowing
X.I getty
Xto continue.  Both
X.B WAITCHAR
Xand
X.B DELAY
Xhave the same effect as specifying
X.B \-r
X.I delay
Xon the command line.
XIf
X.B WAITCHAR
Xis given without a
X.B DELAY,
Xthe result is equal to having said
X.B \-r0
Xon the command line.
X.TP
XTIMEOUT=\fInumber\fR
XAs with the
X.B \-t
X.I timeout
Xcommand line argument, tells
X.I getty
Xto exit if no user name is accepted before the
X.I number
Xof seconds elapse after the login prompt is typed.
X.TP
XALTLOCK=\fIline\fR
X.I Uugetty
Xuses this parameter to lock an alternate device, in addition to the
Xone it is attached to.  This is for those systems that have two
Xdifferent device names that refer to the same physical port; e.g.
X/dev/tty1A vs. /dev/tty1a, where one uses modem control and the
Xother doesn't.  See the section on UUGETTY for more details.
X.P
XThe name of the defaults file can be changed by specifying
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
X.\" Nothing,
X.\" | else (trs16)
X.B \-d)
X.\" | M4_end (trs16)
X.\" +----------
X.I defaults_file
Xon the command line.  If
X.I defaults_file
Xbegins with a slash, it is assumed to be a complete pathname of the
Xdefaults file to be used.  Otherwise, it is assumed to be a regular
Xfilename, causing
X.I getty
Xto use the pathname
X.B _defaults_`/\fIdefaults_file\fR.'
X.SH "PROMPT SUBSTITUTIONS"
XWhen
X.I getty
Xis typing
X.\" +----------
X.\" | M4_start (issue)
Xifdef(`_issue_',
Xthe issue or login banner (ususally
X.B _issue_\fR)`,'
Xor,
X.\" | else (issue)
X.\")
X.\" | M4_end (issue)
X.\" +----------
Xthe
X.I login\-prompt,
Xit recognizes several escape (quoted) characters.  When one of these
Xquoted characters is found, its value is substituted in the output
Xproduced by
X.I getty.
XRecognized escape characters are:
X.nf
X
X\\\\	Backslash (\\).
X
X\\b	Backspace (^H).
X
X\\c	Placed at the end of a string, this prevents
X	a new\-line from being typed after the string.
X
X\\f	Formfeed (^L).
X
X\\n	New\-line (^J).
X
X\\r	Carriage\-return (^M).
X
X\\s	A single space (' ').
X
X\\t	Horizontal tab (^I).
X
X\\\fInnn\fR	Outputs the ASCII character whose octal value
X	is \fInnn\fR.
X
X.fi
XIn addition, a single backslash at the end of a line causes the
Ximmediately following new\-line to be ignored, allowing continuation
Xlines.
X.PP
XAlso, certain
X.B @\fIchar\fR
Xparameters are recognized.  Those parameters, and the value that is
Xsubstituted for them are:
X.TP 5
X@B
XThe current (evaluated at the time the
X.B @B
Xis seen) baud rate.
X.TP
X@D
XThe current date, in MM/DD/YY format.
X.TP
X@L
XThe
X.I line
Xto which
X.I getty
Xis attached.
X.TP
X@S
XThe system node name.
X.TP
X@T
XThe current time, in HH:MM:SS (24-hour) format.
X.TP
X@U
XThe number of currently signed\-on users.  This is a count of the
Xnumber of entries in the
X.I _utmp_
Xfile
X.\" +----------
X.\" | M4_start (logutmp)
Xifdef(`logutmp',
Xwhose ut_type field is LOGIN_PROCESS.,
X.\" | else (logutmp)
Xthat have a non\-null ut_name field.)
X.\" | M4_end (logutmp)
X.\" +----------
X.TP
X@V
XThe value of
X.B VERSION\fR,
Xas given in the defaults file.
X.P
XTo display a single '@' character, use either '\\@' or '@@'.
X.SH "LINE INITIALIZATION"
XOne of the greatest benefits (in the author's opinion, at least) is
Xthe ability of
X.I getty
Xto initialize its line before use.  This will most likely be done on
Xlines with modems, not terminals, although initializing terminals is
Xnot out of the question.
X.PP
XLine initialization is accomplished by placing an
X
X.in +.5i
XINIT=\fIstring\fR
X.in -.5i
X
Xline in the defaults file.
X.I String
Xis a series of one or more fields in the form
X
X.in +.5i
Xsend [ expect [ send [ expect ] ] ... ]
X.in -.5i
X
XThis format resembles the expect/send sequences used in the UUCP
X.I L.sys
Xor
X.I Systems
Xfile, with the following exceptions:
X.TP 3
X1.
XThe expect/send pairs are reversed.  That is, the first sequence
Xgiven is 'sent', not 'expected'.
X.TP
X2.
XA carriage return is NOT appended automatically to sequences that
Xare 'sent'.  If you want a carriage\-return sent, you must explicitly
Xshow it, with '\\r'.
X.P
X.I Getty
Xsupports subfields in the expect field of the form
X
X.in +.5i
Xexpect[\-send\-expect]...
X.in -.5i
X
Xas with UUCP.  All the escape characters (those beginning with a '\\'
Xcharacter) listed in the PROMPT SUBSTITUTIONS section are valid in
Xthe send and expect fields.
XIn addition, the following two escape characters are recognized:
X.nf
X
X\\p	Inserts a 1\-second delay.
X
X\\d	Inserts a 2\-second delay.
X
X.fi
XNote that for these two escape characters, no actual character is sent.
X.SH UUGETTY
X.I Uugetty
Xhas identical behavior to
X.I getty,
Xexcept that
X.I uugetty
Xis designed to create and use the lock files maintained by the UUCP
Xfamily
X.I (uucp(_cmd_section_), cu(_cmd_section_)
Xand others).  This prevents two or more processes from having conficting
Xuse of a tty line.
X.PP
XWhen
X.I uugetty
Xstarts up, if it sees a lock file on the line it intends to use,
Xit will use the pid in the lock file to see if there is an active
Xprocess holding the lock.  If not,
X.I uugetty
Xwill remove the lock file and continue.  If a valid process is found,
X.I uugetty
Xwill sleep until that process releases the lock and then it will exit,
Xforcing
X.I init(_mcmd_section_)
Xto spawn a new
X.I uugetty.
XOnce no conflicting process is found,
X.I uugetty
Xgrabs the
X.I line
Xby creating the lock file itself before issuing the login prompt.
XThis prevents other processes from using the line.  Judicious use
Xof the
X.B \-r\fIdelay\fR
Xargument (or with
X.B WAITCHAR=YES
Xand
X.B DELAY=\fIdelay\fR)
Xwill prevent
X.I uugetty
Xfrom locking the line until a user attempts to login.
X.PP
X.I Uugetty
Xwill normally only lock the name of the line it is running on.  On
Xsystems where there are two device names referring to the same port
X(as is the case where one device uses modem control while the other
Xdoesn't), place a line of the form
X
X.in +.5i
XALTLOCK=\fIline\fR
X.in -.5i
X
Xline in the defaults file.  For instance, if
X.I uugetty
Xis on
X.I /dev/tty1a,
Xand you want to have it lock
X.I /dev/tty1A
Xalso, use the line
X.B ALTLOCK=tty1A
Xin the defaults file.
X.SH FILES
X.TP 16
X_console_
XThe device to which errors are reported.
X.\" +----------
X.\" | M4_start (trymail)
Xifdef(`trymail',
XIf the device is for some reason unavailable (cannot be written to)`,'
Xa mail message containing the error is sent to the user
X.B _notify_\fR.,
X.\" | else (trymail)
X.\")
X.\" | M4_end (trymail)
X.\" +----------
X.TP
X_defaults_`/getty'
XContains the runtime configuration.  Note that
X.I uugetty
Xuses _defaults_`/uugetty\fR.'
X.TP
X_gettytab_
XContains speed and tty settings to be used by
X.I getty.
X.\" +----------
X.\" | M4_start (issue)
Xifdef(`_issue_',
X.TP
X_issue_
XThe default issue (or login banner).
X.\" | else (issue)
X.\")
X.\" | M4_end (issue)
X.\" +----------
X.TP
X_login_
XThe default login program called after the user's name is entered.
X.\" +----------
X.\" | M4_start (ttytype)
Xifdef(`ttytype',
X.TP
X_ttytype_
XContains the terminal types for each line in the system.,
X.\" | else (ttytype)
X.\")
X.\" | M4_end (ttytype)
X.\" +----------
X.P
X.SH "SEE ALSO"
Xinit(_mcmd_section_),
Xlogin(_mcmd_section_),
Xuucp(_cmd_section_),
Xioctl(_system_section_),
Xuname(_library_section_),
X.\" +----------
X.\" | M4_start (issue)
Xifdef(`issue',
Xissue`('_file_section_`)',
X.\" | else (issue)
X.\")
X.\" | M4_end (issue)
X.\" +----------
X_gtab_`('_file_section_),
Xutmp(_file_section_),
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
Xtty`('_misc_section_`)',
X.\" | else (trs16)
Xtermio`('_misc_section_`)')
X.\" | M4_end (trs16)
X.\" +----------
X.SH AUTHOR
X.nf
XPaul Sutcliffe, Jr.  <paul@devon.lns.pa.us>
XUUCP: ...!rutgers!devon!paul
!STUFFY!FUNK!
echo Extracting table.c
sed >table.c <<'!STUFFY!FUNK!' -e 's/X//'
X/*
X**	$Id: table.c,v 1.1 90/01/16 16:18:56 paul Exp Locker: paul $
X**
X**	Routines to process the gettytab file.
X*/
X
X/*
X**	Copyright 1989,1990 by Paul Sutcliffe Jr.
X**
X**	Permission is hereby granted to copy, reproduce, redistribute,
X**	or otherwise use this software as long as: there is no monetary
X**	profit gained specifically from the use or reproduction or this
X**	software, it is not sold, rented, traded or otherwise marketed,
X**	and this copyright notice is included prominently in any copy
X**	made.
X**
X**	The author make no claims as to the fitness or correctness of
X**	this software for any use whatsoever, and it is provided as is. 
X**	Any use of this software is at the user's own risk.
X*/
X
X/*
X**	$Log:	table.c,v $
X**	Revision 1.1  90/01/16  16:18:56  paul
X**	Initial revision
X**	
X*/
X
X
X#include "getty.h"
X#include "table.h"
X
X#if defined(RCSID) && !defined(lint)
Xstatic char *RcsId =
X"@(#)$Id: table.c,v 1.1 90/01/16 16:18:56 paul Exp Locker: paul $";
X#endif
X
X
X/*	Sane conditions.
X */
X#define	ISANE	( BRKINT | IGNPAR | ISTRIP | ICRNL | IXON | IXANY )
X#define	OSANE	( OPOST | ONLCR )
X#define	CSANE	( DEF_CFL | CREAD | HUPCL )
X#define	LSANE	( ISIG | ICANON | ECHO | ECHOE | ECHOK )
X
X#define	CC_SANE	{ CINTR, CQUIT, CERASE, CKILL, CEOF, CNUL, CNUL, CNUL }
X
X
X/*	States for gtabvalue()
X */
X#define	ENTRY	0	/* looking for an entry line */
X#define	QUIT	1	/* error occurred */
X
X
X#define	NULLPTR		(char *) NULL
X
X
X/*	All possible mode flags.
X */
X
XSYMTAB	imodes[] = {
X	{ "IGNBRK",	IGNBRK	},
X	{ "BRKINT",	BRKINT	},
X	{ "IGNPAR",	IGNPAR	},
X	{ "PARMRK",	PARMRK	},
X	{ "INPCK",	INPCK	},
X	{ "ISTRIP",	ISTRIP	},
X	{ "INLCR",	INLCR	},
X	{ "IGNCR",	IGNCR	},
X	{ "ICRNL",	ICRNL	},
X	{ "IUCLC",	IUCLC	},
X	{ "IXON",	IXON	},
X	{ "IXANY",	IXANY	},
X	{ "IXOFF",	IXOFF	},
X	{  NULLPTR,	0	}
X};
X
XSYMTAB	omodes[] = {
X	{ "OPOST",	OPOST	},
X	{ "OLCUC",	OLCUC	},
X	{ "ONLCR",	ONLCR	},
X	{ "OCRNL",	OCRNL	},
X	{ "ONOCR",	ONOCR	},
X	{ "ONLRET",	ONLRET	},
X	{ "OFILL",	OFILL	},
X	{ "OFDEL",	OFDEL	},
X	{ "NLDLY",	NLDLY	},
X	{ "NL0",	NL0	},
X	{ "NL1",	NL1	},
X	{ "CRDLY",	CRDLY	},
X	{ "CR0",	CR0	},
X	{ "CR1",	CR1	},
X	{ "CR2",	CR2	},
X	{ "CR3",	CR3	},
X	{ "TABDLY",	TABDLY	},
X	{ "TAB0",	TAB0	},
X	{ "TAB1",	TAB1	},
X	{ "TAB2",	TAB2	},
X	{ "TAB3",	TAB3	},
X	{ "BSDLY",	BSDLY	},
X	{ "BS0",	BS0	},
X	{ "BS1",	BS1	},
X	{ "VTDLY",	VTDLY	},
X	{ "VT0",	VT0	},
X	{ "VT1",	VT1	},
X	{ "FFDLY",	FFDLY	},
X	{ "FF0",	FF0	},
X	{ "FF1",	FF1	},
X	{  NULLPTR,	0	}
X};
X
XSYMTAB	cmodes[] = {
X	{ "B0",		B0	},
X	{ "B50",	B50	},
X	{ "B75",	B75	},
X	{ "B110",	B110	},
X	{ "B134",	B134	},
X	{ "B150",	B150	},
X	{ "B200",	B200	},
X	{ "B300",	B300	},
X	{ "B600",	B600	},
X	{ "B1200",	B1200	},
X	{ "B1800",	B1800	},
X	{ "B2400",	B2400	},
X	{ "B4800",	B4800	},
X	{ "B9600",	B9600	},
X#ifdef	B19200
X	{ "B19200",	B19200	},
X#endif	/* B19200 */
X	{ "EXTA",	EXTA	},
X	{ "EXTB",	EXTB	},
X	{ "CS5",	CS5	},
X	{ "CS6",	CS6	},
X	{ "CS7",	CS7	},
X	{ "CS8",	CS8	},
X	{ "CSTOPB",	CSTOPB	},
X	{ "CREAD",	CREAD	},
X	{ "PARENB",	PARENB	},
X	{ "PARODD",	PARODD	},
X	{ "HUPCL",	HUPCL	},
X	{ "CLOCAL",	CLOCAL	},
X#ifdef	LOBLK
X	{ "LOBLK",	LOBLK	},
X#endif	/* LOBLK */
X	{  NULLPTR,	0	},
X};
X
XSYMTAB	lmodes[] = {
X	{ "ISIG",	ISIG	},
X	{ "ICANON",	ICANON	},
X	{ "XCASE",	XCASE	},
X	{ "ECHO",	ECHO	},
X	{ "ECHOE",	ECHOE	},
X	{ "ECHOK",	ECHOK	},
X	{ "ECHONL",	ECHONL	},
X	{ "NOFLSH",	NOFLSH	},
X#ifdef	XCLUDE
X	{ "XCLUDE",	XCLUDE	},
X#endif	/* XCLUDE */
X	{  NULLPTR,	0	}
X};
X
XSYMTAB	ldiscs[] = {
X	{ "LDISC0",	LDISC0	},
X	{  NULLPTR,	0	}
X};
X
X/*
X *	Gettytab entry to use if no other can be determined
X */
XGTAB	Default = {
X	"default",
X	{ 0, 0, ( SSPEED | CSANE ), 0, 0, CC_SANE, },
X	{ ISANE, OSANE, ( SSPEED | CSANE ), LSANE, LDISC0, CC_SANE, },
X	"login: ",
X	"default"
X};
X
X#define	VALUE(cptr)	((cptr == (char *) NULL) ? "NULL" : cptr)
X
Xint	errors = 0;
X
Xint	nextentry(), parseGtab(), findsym();
Xchar	*nextword();
Xvoid	addfield(), chkerr();
X
X
X/*
X**	gtabvalue() - find a gettytab entry that matches "id."
X**
X**	Returns (GTAB *)NULL if not found or an error occurs.
X*/
X
XGTAB *
Xgtabvalue(id)
XReg1 char *id;
X{
X	Reg2 int state;
X	Reg3 char *p;
X	Reg4 char *gettytab;		/* gettytab file to use */
X	STDCHAR buf[MAXLINE+1];		/* buffer for Gtab entries */
X	char buf_id[MAXID+1];		/* buffer to compare initial label */
X	char *this = "First";		/* First or Next entry */
X	static GTAB gtab;		/* structure to be returned */
X	FILE *fp;
X
X	debug3(D_GTAB, "gtabvalue(%s) called\n", VALUE(id));
X
X	gettytab = (Check) ? CheckFile : GETTYTAB;
X	debug3(D_GTAB, "gettytab=%s\n", gettytab);
X
X	/* open the gettytab file
X	 */
X	if ((fp = fopen(gettytab, "r")) == (FILE *) NULL) {
X		(void) sprintf(MsgBuf, "cannot open %s", gettytab);
X		logerr(MsgBuf);
X		return(&Default);
X	}
X
X	/* search through the file for "id", unless
X	 * id is NULL, in which case we drop down
X	 * to get the 'default' entry.
X	 */
X	state = (!Check && (id == (char *) NULL)) ? QUIT : ENTRY;
X
X	while (state != QUIT && nextentry(buf, sizeof(buf), fp) == SUCCESS) {
X		if (buf[0] == '#' || buf[0] == '\n')
X			continue;	/* keep looking */
X		if (Check) {
X			(void) printf("*** %s Entry ***\n", this);
X			(void) printf("%s\n", buf);
X			this = "Next";
X		}
X		if (buf[strlen(buf)-1] != '\n') {
X			/* last char not \n, line is too long */
X			chkerr("line too long", FAIL);
X			state = QUIT;
X			continue;
X		}
X		/* get the first (label) field
X		 */
X		(void) strncpy(buf_id, buf, MAXID);
X		if ((p = strtok(buf_id, "# \t")) != (char *) NULL)
X			*(--p) = '\0';
X		/* if Check is set, parse all entries;
X		 * otherwise, parse only a matching entry
X		 */
X		if (Check || strequal(id, buf_id)) {
X			if (parseGtab(&gtab, buf) == FAIL) {
X				chkerr("*** Invalid Entry ***", FAIL);
X				state = QUIT;
X				continue;
X			}
X			if (!Check) {
X				(void) fclose(fp);
X				return(&gtab);
X			}
X		}
X	}
X
X	if (Check) {
X		if (errors)
X			(void) printf("*** %d errors found ***\n", errors);
X		(void) printf("*** Check Complete ***\n");
X		(void) fclose(fp);
X		return((GTAB *) NULL);
X	}
X
X	/* matching entry not found or defective;
X	 * use the first line of the file
X	 */
X	if (id != (char *) NULL) {
X		(void) sprintf(MsgBuf, "%s entry for \"%s\" not found",
X				gettytab, id);
X		logerr(MsgBuf);
X	}
X	rewind(fp);
X	(void) nextentry(buf, sizeof(buf), fp);
X	(void) fclose(fp);
X	if (parseGtab(&gtab, buf) == FAIL)
X		return(&Default);	/* punt: first line defective */
X
X	debug2(D_GTAB, "gtabvalue() successful\n");
X	return(&gtab);
X}
X
X
X/*
X**	nextentry() - retrieve next entry from gettytab file
X**
X**	Returns FAIL if an error occurs.
X*/
X
Xint
Xnextentry(buf, len, stream)
XReg1 char *buf;
XReg2 int len;
XFILE *stream;
X{
X	Reg3 int count = 0;
X	STDCHAR line[MAXLINE+1];
X
X	*buf = '\0';		/* erase buffer */
X
X	while (fgets(line, sizeof(line), stream) != (char *) NULL) {
X		debug2(D_GTAB, "line read = (");
X		debug1(D_GTAB, line);
X		debug2(D_GTAB, ")\n");
X		if (count)
X			buf[strlen(buf)-1] = '\0';
X		if ((count += strlen(line)) >= len)
X			return(FAIL);		/* entry too long */
X		(void) strcat(buf, line);
X		if (line[0] == '\n')
X			return(SUCCESS);	/* blank line */
X	}
X
X	return(QUIT);
X}
X
X
X/*
X**	parseGtab() - fill in GTAB structure from buffer
X**
X**	Returns FAIL if an error occurs.
X*/
X
Xint
XparseGtab(gtab, line)
XGTAB *gtab;
XReg1 char *line;
X{
X	Reg2 int field;
X	Reg3 char *p;
X	static int count;
X	static char p_cur[MAXID+1], p_next[MAXID+1];
X	static char p_login[MAXLOGIN+1];
X
X	debug2(D_GTAB, "parseGtab() called\n");
X
X	/* initialize gtab to empty
X	 */
X	gtab->cur_id = (char *) NULL;
X	gtab->itermio.c_iflag = 0;
X	gtab->itermio.c_oflag = 0;
X	gtab->itermio.c_cflag = 0;
X	gtab->itermio.c_lflag = 0;
X	gtab->itermio.c_line  = 0;
X	gtab->ftermio.c_iflag = 0;
X	gtab->ftermio.c_oflag = 0;
X	gtab->ftermio.c_cflag = 0;
X	gtab->ftermio.c_lflag = 0;
X	gtab->ftermio.c_line  = 0;
X	gtab->login = (char *) NULL;
X	gtab->next_id = (char *) NULL;
X
X	if (LineD != (char *) NULL) {	/* line disc given on command line */
X		addfield(&(gtab->itermio), LineD);
X		addfield(&(gtab->ftermio), LineD);
X	}
X
X	/* parse the line
X	 */
X	debug2(D_GTAB, "parsing line:\n");
X	field = 1;
X	while (field != FAIL && field != SUCCESS) {
X		if ((p = nextword(line, &count)) == (char *) NULL) {
X			field = FAIL;
X			continue;
X		}
X		debug4(D_GTAB, "field=%d, nextword=(%s)\n", field, p);
X		switch (field) {
X		case 1:
X			/* cur_id label
X			 */
X			(void) strncpy(p_cur, p, MAXID);
X			gtab->cur_id = p_cur;
X			field++;
X			break;
X		case 2:
X			/* '#' field separator
X			 */
X			if (*p != '#') {
X				field = FAIL;
X				continue;
X			}
X			field++;
X			break;
X		case 3:
X			/* initial termio flags
X			 */
X			if (*p == '#')
X				field++;
X			else
X				addfield(&(gtab->itermio), p);
X			break;
X		case 4:
X			/* final termio flags
X			 */
X			if (*p == '#')
X				field++;
X			else
X				addfield(&(gtab->ftermio), p);
X			break;
X		case 5:
X			/* login message --
X			 * nextword won't be the whole message; look
X			 * ahead to the next '#' and terminate string there
X			 */
X			if ((p = strchr(line, '#')) == (char *) NULL) {
X				field = FAIL;
X				continue;
X			}
X			*p = '\0';
X			p = line;		/* point p to line again */
X			count = strlen(p)+1;	/* adjust count accordingly */
X			debug3(D_GTAB, "login=(%s)\n", p);
X			(void) strncpy(p_login, p, MAXLOGIN);
X			gtab->login = p_login;
X			field++;
X			break;
X		case 6:
X			/* next_id label
X			 */
X			(void) strncpy(p_next, p, MAXID);
X			gtab->next_id = p_next;
X			field = SUCCESS;
X			continue;
X		}
X		/* skip over word just processed
X		 */
X		line += count;
X	}
X
X	if (Check) {
X		(void) printf("id: \"%s\"\n", gtab->cur_id);
X		(void) printf("initial termio flags:\n");
X		(void) printf(" iflag: %o, oflag: %o, cflag: %o, lflag: %o\n",
X				gtab->itermio.c_iflag, gtab->itermio.c_oflag,
X				gtab->itermio.c_cflag, gtab->itermio.c_lflag);
X		(void) printf(" line disc: %o\n", gtab->itermio.c_line);
X		(void) printf("final termio flags:\n");
X		(void) printf(" iflag: %o, oflag: %o, cflag: %o, lflag: %o\n",
X				gtab->ftermio.c_iflag, gtab->ftermio.c_oflag,
X				gtab->ftermio.c_cflag, gtab->ftermio.c_lflag);
X		(void) printf(" line disc: %o\n", gtab->ftermio.c_line);
X		(void) printf("login prompt: \"%s\"\n", gtab->login);
X		(void) printf("next id: \"%s\"\n\n", gtab->next_id);
X	}
X
X	return(field);
X}
X
X
X/*
X**	nextword() - get next "word" from buffer
X*/
X
Xchar *
Xnextword(buf, count)
XReg1 char *buf;
XReg4 int *count;
X{
X	Reg2 int num = 0;
X	Reg3 char *p;
X	static char word[MAXLINE+1];
X
X	while (*buf == ' ' || *buf == '\t' || *buf == '\\' ||
X	       *buf == '\n') {	/* skip leading whitespace */
X		buf++; num++;
X	}
X	p = word;
X	if (*buf == '#') {	/* first char is '#' ? */
X		*p++ = *buf;
X		num++;
X	} else {
X		while (*buf != ' ' && *buf != '\t' && *buf != '\\' &&
X		       *buf != '#' && *buf != '\n') {
X			*p++ = *buf++;
X			num++;
X		}
X	}
X	*p = '\0';
X	*count = num;
X	return(word);
X}
X
X
X/*
X**	addfield() - add symbol to termio structure
X*/
X
Xvoid
Xaddfield(termio, field)
XReg2 TERMIO *termio;
XReg3 char *field;
X{
X	Reg1 int val;
X
X	if (strequal(field, "SANE")) {
X		termio->c_iflag |= ISANE;
X		termio->c_oflag |= OSANE;
X		termio->c_cflag |= CSANE;
X		termio->c_lflag |= LSANE;
X	} else {
X		if ((val = findsym(field, imodes)) != FAIL)
X			termio->c_iflag |= (ushort) val;
X		else if ((val = findsym(field, omodes)) != FAIL)
X			termio->c_oflag |= (ushort) val;
X		else if ((val = findsym(field, cmodes)) != FAIL)
X			termio->c_cflag |= (ushort) val;
X		else if ((val = findsym(field, lmodes)) != FAIL)
X			termio->c_lflag |= (ushort) val;
X		else if ((val = findsym(field, ldiscs)) != FAIL)
X			termio->c_line |= (ushort) val;
X		else if (Check) {
X			(void) sprintf(MsgBuf, "undefined symbol: %s", field);
X			chkerr(MsgBuf, OK);
X		}
X	}
X}
X
X
X/*
X**	findsym() - look for field in SYMTAB list
X*/
X
Xint
Xfindsym(field, symtab)
XReg1 char *field;
XReg2 SYMTAB *symtab;
X{
X	for (; symtab->symbol != (char *) NULL; symtab++)
X		if (strequal(symtab->symbol, field))
X			return((int) symtab->value);
X
X	return(FAIL);
X}
X
X
X/*
X**	chkerr() - display error message from check routines
X*/
X
Xvoid
Xchkerr(msg, status)
Xchar *msg;
Xint status;
X{
X	(void) printf("*** parsing error: %s ***\n", msg);
X	if (status)
X		(void) printf("*** checking halted ***\n");
X	else
X		(void) printf("*** checking continued ***\n");
X
X	errors++;
X}
X
X
X/* end of table.c */
!STUFFY!FUNK!
echo Extracting defaults.c
sed >defaults.c <<'!STUFFY!FUNK!' -e 's/X//'
X/*
X**	$Id: defaults.c,v 1.1 90/01/16 16:13:23 paul Exp Locker: paul $
X**
X**	Routines to access runtime defaults file.
X**	This is to allow program features to be configured
X**	without the need to recompile.
X**
X**	XENIX has defopen(S) and defread(S), but I think this is better,
X**	since it reads the file only once, storing the values in core.
X**	It is certainly more portable.
X*/
X
X/*
X**	Copyright 1989,1990 by Paul Sutcliffe Jr.
X**
X**	Permission is hereby granted to copy, reproduce, redistribute,
X**	or otherwise use this software as long as: there is no monetary
X**	profit gained specifically from the use or reproduction or this
X**	software, it is not sold, rented, traded or otherwise marketed,
X**	and this copyright notice is included prominently in any copy
X**	made.
X**
X**	The author make no claims as to the fitness or correctness of
X**	this software for any use whatsoever, and it is provided as is. 
X**	Any use of this software is at the user's own risk.
X*/
X
X/*
X**	$Log:	defaults.c,v $
X**	Revision 1.1  90/01/16  16:13:23  paul
X**	Initial revision
X**	
X*/
X
X
X#include "getty.h"
X#include "defaults.h"
X#include <sys/stat.h>
X#include <errno.h>
X
X#if defined(RCSID) && !defined(lint)
Xstatic char *RcsId =
X"@(#)$Id: defaults.c,v 1.1 90/01/16 16:13:23 paul Exp Locker: paul $";
X#endif
X
X#ifndef DEFAULTS
X#define DEFAULTS  "/etc/default/%s"	/* location of defaults file */
X#endif	/* DEFAULTS */
X
X#ifndef	MAXLINE
X#define	MAXLINE	256	/* maximum # chars in a line */
X#endif	/* MAXLINE */
X
X#ifndef MAXDEF
X#define MAXDEF  100	/* maximum # of lines in defaults file */
X#endif	/* MAXDEF */
X
X
X/*
X**	defbuild() - create in-core list of defaults
X**
X**	Returns (DEF**)NULL if no defaults file found or an error occurs.
X*/
X
XDEF **
Xdefbuild(filename)
Xchar *filename;
X{
X	Reg1 int i;
X	Reg2 DEF *dp;
X	Reg3 DEF *next;
X	FILE *fp;
X	char *fname, defname[MAXLINE+1], buf[MAXLINE+1];
X	static DEF *deflist[MAXDEF+1];		/* in-core list */
X	struct stat st;
X	extern int errno;
X
X	debug3(D_DEF, "defbuild(%s) called\n",
X			((filename == (char *) NULL) ? "NULL" : filename));
X
X	/* look to see if there's a DEFAULTS/MyName.Device file
X	 */
X	(void) sprintf(buf, "%s", DEFAULTS);
X	(void) strcat(buf, ".%s");
X	(void) sprintf(defname, buf, MyName, Device);
X	debug3(D_DEF, "looking for %s\n", defname);
X	if ((stat(defname, &st) == FAIL) && errno == ENOENT) {	/* Nope */
X		debug2(D_DEF, "stat failed, no file\n");
X		(void) sprintf(defname, DEFAULTS, MyName);
X	}
X
X	fname = (filename != (char *) NULL) ? filename : defname;
X
X	/* if fname doesn't begin with a '/', assume it's a
X	 * filename to be made "DEFAULTS/fname"
X	 */
X	if (*fname != '/') {
X		(void) sprintf(defname, DEFAULTS, fname);
X		fname = defname;
X	}
X
X	debug3(D_DEF, "fname = (%s)\n", fname);
X
X	if ((fp = defopen(fname)) == (FILE *) NULL) {
X		debug2(D_DEF, "defopen() failed\n");
X		return((DEF **) NULL);		/* couldn't open file */
X	}
X
X	for (i=0; i < MAXDEF; i++) {
X		if ((dp = defread(fp)) == (DEF *) NULL)
X			break;
X		if ((next = (DEF *) malloc((unsigned) sizeof(DEF))) ==
X		    (DEF *) NULL) {
X			logerr("malloc() failed: defaults list truncated");
X			break;
X		}
X		next->name = dp->name;
X		next->value = dp->value;
X		deflist[i] = next;
X		debug5(D_DEF, "deflist[%d]: name=(%s), value=(%s)\n",
X				i, deflist[i]->name, deflist[i]->value);
X	}
X	deflist[i] = (DEF *) NULL;	/* terminate list */
X	(void) defclose(fp);
X	debug2(D_DEF, "defbuild() successful\n");
X	return(deflist);
X}
X
X
X/*
X**	defvalue() - locate the value in "deflist" that matches "name"
X**
X**	Returns (char*)NULL if no match is made.
X*/
X
Xchar *
Xdefvalue(deflist, name)
XReg1 DEF **deflist;
XReg2 char *name;
X{
X	debug3(D_DEF, "defvalue(%s) called\n", name);
X
X	if (deflist != (DEF **) NULL)
X		for (; *deflist != (DEF *) NULL; *deflist++)
X			if (strequal(name, (*deflist)->name)) {
X				debug3(D_DEF, "defvalue returns (%s)\n",
X						(*deflist)->value);
X				return((*deflist)->value);  /* normal exit */
X			}
X
X	debug2(D_DEF, "defvalue returns NULL\n");
X	return((char *) NULL);
X}
X
X
X/*
X**	defopen() - open the defaults file
X**
X**	Returns (FILE*)NULL if file not found or an error occurs.
X*/
X
XFILE *
Xdefopen(filename)
XReg1 char *filename;
X{
X	if (filename != (char *) NULL)
X		return(fopen(filename, "r"));
X
X	return((FILE *) NULL);
X}
X
X
X/*
X**	defread() - read a line from the defaults file
X**
X**	Returns (DEF*)NULL if an error occurs.
X*/
X
XDEF *
Xdefread(fp)
XReg2 FILE *fp;
X{
X	Reg1 char *p;
X	STDCHAR buf[MAXLINE+1];	/* buffer large enough for 1 line */
X	static DEF def;
X
X	do {
X		if (fgets(buf, sizeof(buf), fp) == (char *) NULL)
X			return((DEF *) NULL);	/* no more lines */
X
X	} while (buf[0] == '#');		/* ignore comment lines */
X
X	buf[strlen(buf)-1] = '\0';		/* rm trailing \n */
X
X	/* lines should be in the form "NAME=value"
X	 */
X	if ((p = strchr(buf, '=')) == (char *) NULL) {
X		(void) sprintf(MsgBuf, "bad defaults line: %s", buf);
X		logerr(MsgBuf);
X		return((DEF *) NULL);
X	}
X	*p++ = '\0';		/* split into two fields, name and value */
X	def.name = strdup(buf);
X	def.value = strdup(p);
X
X	return(&def);
X}
X
X
X/*
X**	defclose() - closes the defaults file
X**
X**	Returns EOF if an error occurs.
X*/
X
Xint
Xdefclose(fp)
XReg1 FILE *fp;
X{
X	return(fclose(fp));
X}
X
X
X/* end of defaults.c */
!STUFFY!FUNK!
echo Extracting man/gettytab.m4
sed >man/gettytab.m4 <<'!STUFFY!FUNK!' -e 's/X//'
X.\" +----------
X.\" |	$Id: gettytab.m4,v 1.1 90/01/16 16:02:17 paul Exp Locker: paul $
X.\" |
X.\" |	GETTYTAB man page.
X.\" |
X.\" |	Copyright 1989,1990 by Paul Sutcliffe Jr.
X.\" |
X.\" |	Permission is hereby granted to copy, reproduce, redistribute,
X.\" |	or otherwise use this software as long as: there is no monetary
X.\" |	profit gained specifically from the use or reproduction or this
X.\" |	software, it is not sold, rented, traded or otherwise marketed,
X.\" |	and this copyright notice is included prominently in any copy
X.\" |	made.
X.\" |
X.\" |	The author make no claims as to the fitness or correctness of
X.\" |	this software for any use whatsoever, and it is provided as is. 
X.\" |	Any use of this software is at the user's own risk.
X.\" |
X.\"
X.\" +----------
X.\" |	$Log:	gettytab.m4,v $
X.\" |	Revision 1.1  90/01/16  16:02:17  paul
X.\" |	Initial revision
X.\" |	
X.\" |	
X.\" 
X.\" +----------
X.\" | M4 configuration
X.\"
Xinclude(config.m4).\"
X.\"
X.\" define(`_temp_', maketemp(m4bXXXXX))
X.\" syscmd(echo _gtab_ | tr "[a-z]" "[A-Z]" | tr -d "\012" > _temp_)
X.\" define(`_GTAB_', include(_temp_))
X.\" syscmd(rm -f _temp_)
X.\"
X.\" +----------
X.\" | Manpage source follows:
X.\"
X.TH _GTAB_ _file_section_
X.SH NAME
X_gtab_ \- speed and tty settings used by getty
X.SH DESCRIPTION
XThe file
X.B _gettytab_
Xcontains information used by
X.I getty(_mcmd_section_)
Xto set up the speed and tty settings for a line.  It supplies
Xinformation on what the
X.I login-prompt
Xshould look like.  It also supplies the speed to try next if
Xthe user indicates the current speed is not correct by typing a
X.I <break>
Xcharacter.
X.PP
XEach entry in
X.B _gettytab_
Xhas the following format:
X
X.in +.2i
X.ll 7.5i
Xlabel# initial-flags # final-flags # login-prompt #next-label
X.ll
X.in -.2i
X
XEach entry is followed by a blank line.  Lines that begin with
X.B \#
Xare ignored and may be used to comment the file.  The various
Xfields can contain quoted characters of the form
X.B \\\\b\fR, \fB\\\\n\fR, \fB\\\\c\fR,
Xetc., as well as
X.B \\\\\fInnn\fR,
Xwhere
X.I nnn
Xis the octal value of the desired character.  The various fields are:
X.TP 16
X.I label
XThis is the string against which
X.I getty
Xtries to match its second argument. It is often the speed, such as
X.B 1200\fR,
Xat which the terminal is supposed to run, but it needn't be (see below).
X.TP
X.I initial-flags
XThese flags are the initial
X.I ioctl(_system_section_)
Xsettings to which the terminal is to be set if a terminal type is
Xnot specified to
X.I getty\fR.
X.I Getty
Xunderstands the symbolic names specified in
X.B /usr/`include'/termio.h
X(see
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
X.I tty`('_misc_section_`)).',
X.\" | else (trs16)
X.I termio`('_misc_section_`)).')
X.\" | M4_end (trs16)
X.\" +----------
XNormally only the speed flag is required in the
X.I initial-flags
Xfield.
X.I Getty
Xautomatically sets the terminal to raw input mode and takes care of
Xmost of the other flags.  The
X.I initial-flag
Xsettings remain in effect until
X.I getty
Xexecutes
X.I login(_mcmd_section_).
X.TP
X.I final-flags
XThese flags take the same values as the
X.I initial-flags
Xand are set just prior to
X.I getty
Xexecutes
X.B _login_\fR.
XThe speed flag is again required.  The composite flag
X.B SANE
Xtakes care of most of the other flags that need to be set so that
Xthe processor and terminal are communicating in a rational fashion.
XThe other two commonly specified
X.I final-flags
Xare
X.B TAB3\fR,
Xso that tabs are sent to the terminal as spaces, and
X.B HUPCL\fR,
Xso that the line is hung up on the final close.
X.TP
X.I login-prompt
XThis entire field is printed as the
X.I login-prompt\fR.
XUnlike the above fields where white space is ignored (a space,
Xtab or new-line), they are included in the
X.I login-prompt
Xfield.
X
XThe
X.I login-prompt
Xmay contain various
X.B @\fIchar\fR
Xand
X.B \\\\\fIchar\fR
Xparameters.  These are described in full in the
X.I getty(_mcmd_section_)
Xsection PROMPT SUBSTITUTIONS.
X.TP
X.I next-label
XThis indicates the next
X.I label
Xof the entry in the table that
X.I getty
Xshould use if the user types a
X.I <break>
Xor the input cannot be read.  Usually, a series of speeds are linked
Xtogether in this fashion, into a closed set.  For instance,
X.B 2400
Xlinked to
X.B 1200\fR,
Xwhich in turn is linked to
X.B 300\fR,
Xwhich finally is linked back to
X.B 2400\fR.
X.P
XIf
X.I getty
Xis called without a
X.I speed
Xargument, then the first entry of
X.B _gettytab_
Xis used, thus making the first entry of
X.B _gettytab_
Xthe default entry. It is also used if
X.I getty
Xcan't find the specified
X.I label.
XIf
X.B _gettytab_
Xitself is missing, there is one entry built into
X.I getty
Xwhich will bring up a terminal at
X.B 9600
Xbaud.
X.P
XIt is strongly recommended that after making or modifying
X.B _gettytab_`,'
Xit be run through
X.I getty
Xwith the check (\fB-c\fR) option to be sure there are no errors.
X.SH FILES
X_gettytab_
X.SH "SEE ALSO"
Xlogin(_mcmd_section_),
Xgetty(_mcmd_section_),
Xioctl(_system_section_),
X.\" +----------
X.\" | M4_start (trs16)
Xifdef(`trs16',
Xtty`('_misc_section_`)',
X.\" | else (trs16)
Xtermio`('_misc_section_`)')
X.\" | M4_end (trs16)
X.\" +----------
!STUFFY!FUNK!
echo Extracting config.h.SH
sed >config.h.SH <<'!STUFFY!FUNK!' -e 's/X//'
X:
X# $Id: config.h.SH,v 1.1 90/01/16 16:13:03 paul Exp Locker: paul $
X#
X# Creates config.h file for getty distribution
X#
X# $Log:	config.h.SH,v $
X# Revision 1.1  90/01/16  16:13:03  paul
X# Initial revision
X# 
X#
X
Xcase $CONFIG in
X'')
X    if test ! -f config.sh; then
X	ln ../config.sh . || \
X	ln ../../config.sh . || \
X	ln ../../../config.sh . || \
X	(echo "Can't find config.sh."; exit 1)
X    fi
X    . config.sh
X    ;;
Xesac
Xcase "$0" in
X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
Xesac
Xecho "Extracting config.h (with variable substitutions)"
X$spitshell >config.h <<!GROK!THIS!
X/*
X**	config.h
X**
X**	Getty configuration.
X*/
X
X/*
X**	Copyright 1989,1990 by Paul Sutcliffe Jr.
X**
X**	Permission is hereby granted to copy, reproduce, redistribute,
X**	or otherwise use this software as long as: there is no monetary
X**	profit gained specifically from the use or reproduction or this
X**	software, it is not sold, rented, traded or otherwise marketed,
X**	and this copyright notice is included prominently in any copy
X**	made.
X**
X**	The author make no claims as to the fitness or correctness of
X**	this software for any use whatsoever, and it is provided as is. 
X**	Any use of this software is at the user's own risk.
X*/
X
X
X#include "tune.h"			/* defs needed below */
X
X
X/*  These are set by config.sh.
X *  If you change them here, they will be reset
X *  the next time you run Configure.
X */
X
X#$define	Reg1	  $reg1		/* register declarations */
X#$define	Reg2	  $reg2
X#$define	Reg3	  $reg3
X#$define	Reg4	  $reg4
X#$define	Reg5	  $reg5
X#$define	Reg6	  $reg6
X#$define	Reg7	  $reg7
X#$define	Reg8	  $reg8
X#$define	Reg9	  $reg9
X#$define	Reg10	  $reg10
X#$define	Reg11	  $reg11
X#$define	Reg12	  $reg12
X#$define	Reg13	  $reg13
X#$define	Reg14	  $reg14
X#$define	Reg15	  $reg15
X#$define	Reg16	  $reg16
X
X#$d_portable	PORTABLE		/* compile for more than one site */
X#$d_getutent	GETUTENT		/* we have getutent() and friends */
X#$d_strdup	STRDUP			/* we have strdup() */
X#$d_putenv	PUTENV			/* we have putenv() */
X
X#$d_ttytype	TTYTYPE   "$ttytype"	/* file used to identify terminals */
X#$define	GETTYTAB  "$gettytab"	/* file used for speed/termio table */
X
X#$define	STDCHAR   $stdchar	/* signed or unsigned chars in stdio */
X#$define	UIDTYPE	  $uidtype	/* storage type of UID's */
X#$define	GIDTYPE	  $gidtype	/* storage type of GID's */
X
X#$d_voidsig	VOIDSIG			/* you have 'void (*signal)()' */
X
X#ifdef	VOIDSIG				/* define sig_t appropriately */
Xtypedef	void	sig_t;
X#else	/* VOIDSIG */
Xtypedef	int	sig_t;
X#endif	/* VOIDSIG */
X
X#ifndef	VOIDUSED
X#$define	VOIDUSED  $defvoidused
X#endif
X#$define	VOIDFLAGS $voidflags
X#if (VOIDFLAGS & VOIDUSED) != VOIDUSED
X#$define	void	  int		/* is void to be avoided? */
X#$define	M_VOID			/* Xenix strikes again */
X#endif
X
X#ifndef	PORTABLE
X#$define	HOSTNAME  "$hostname"	/* compile node name in */
X#else
X#$d_douname	DOUNAME			/* use uname() to get node name */
X#$d_phostname	PHOSTNAME "$phostname"	/* get node name from this command */
X#endif
X
X#ifndef	UTMP_FILE
X#$define	UTMP_FILE "$utmp"	/* name of the utmp file */
X#endif
X
X#ifdef	LOGUTMP
X#ifndef	WTMP_FILE
X#$define	WTMP_FILE "$wtmp"	/* name of the wtmp file */
X#endif	/* WTMP_FILE */
X#endif	/* LOGUTMP */
X
X#ifdef	TRYMAIL
X#$define	MAILER	  "$mailer"	/* mail agent */
X#endif
X
X#ifdef	UUGETTY
X#$d_asciipid	ASCIIPID		/* PID stored in ASCII in lock file */
X#$define	LOCK	  "$lock/LCK..%s"	/* lock file name */
X#$define	UUCPID	  $uucpid	/* uid of UUCP account */
X#endif
X
X
X/* end of config.h */
X!GROK!THIS!
Xchmod 644 config.h
X$eunicefix config.h
!STUFFY!FUNK!
echo Extracting putenv.c
sed >putenv.c <<'!STUFFY!FUNK!' -e 's/X//'
X/*
X**	$Id: putenv.c,v 1.1 90/01/16 16:17:33 paul Exp Locker: paul $
X**
X**	Implements putenv(3c).
X*/
X
X/*
X**	Copyright 1989,1990 by Paul Sutcliffe Jr.
X**
X**	Permission is hereby granted to copy, reproduce, redistribute,
X**	or otherwise use this software as long as: there is no monetary
X**	profit gained specifically from the use or reproduction or this
X**	software, it is not sold, rented, traded or otherwise marketed,
X**	and this copyright notice is included prominently in any copy
X**	made.
X**
X**	The author make no claims as to the fitness or correctness of
X**	this software for any use whatsoever, and it is provided as is. 
X**	Any use of this software is at the user's own risk.
X*/
X
X/*
X**	$Log:	putenv.c,v $
X**	Revision 1.1  90/01/16  16:17:33  paul
X**	Initial revision
X**	
X*/
X
X
X#include "getty.h"
X
X#if defined(RCSID) && !defined(lint)
Xstatic char *RcsId =
X"@(#)$Id: putenv.c,v 1.1 90/01/16 16:17:33 paul Exp Locker: paul $";
X#endif
X
X#ifndef	MAXENV
X#define	MAXENV	64	/* max # lines in envorinment */
X#endif	/* MAXENV */
X
X
X/*
X**	putenv() - change or add value to environment
X**
X**	Returns non-zero if an error occurrs, zero otherwise.
X*/
X
Xextern char **environ;
X
Xint
Xputenv(s)
Xchar *s;
X{
X	Reg1 int i;
X	Reg2 char *p;
X	char *q, **envp, *env[MAXENV];
X	boolean match = FALSE;
X
X	if (s == (char *) NULL)
X		return(FAIL);	/* can't add NULL to the environment */
X
X	if ((p = malloc((unsigned) strlen(s)+1)) == (char *) NULL)
X		return(FAIL);	/* malloc failed */
X
X	(void) strcpy(p, s);
X	if ((q = strchr(p, '=')) == (char *) NULL) {
X		free(p);
X		return(FAIL);	/* not in the form ``name=value'' */
X	}
X
X	*q = '\0';		/* split into two fields, name & value */
X
X	/* copy the environ list, replacing `s' if a match is found
X	 */
X	for (i=0, envp=environ; *envp != (char *) NULL; i++, envp++) {
X		if (strnequal(*envp, p, strlen(p))) {
X			match = TRUE;
X			env[i] = s;
X		} else
X			env[i] = *envp;
X	}
X
X	if (!match) {
X		*q = '=';	/* put back the equal sign */
X		env[i++] = p;	/* add p to env list */
X	} else
X		free(p);	/* not needed, s replaced old value */
X
X	env[i++] = (char *) NULL;
X
X	/* now dup env to make new environment
X	 */
X	if ((envp = (char **) malloc((unsigned) (i*sizeof(char *)))) ==
X	    (char **) NULL) {
X		return(FAIL);
X	}
X	environ = envp;		/* point to new area */
X	for (i=0; env[i] != (char *) NULL; i++)
X		*envp++ = env[i];
X	*envp = (char *) NULL;
X
X	return(SUCCESS);
X}
X
X
X/* end of putenv.c */
!STUFFY!FUNK!
echo ""
echo "End of kit 3 (of 4)"
cat /dev/null >kit3isdone
run=''
config=''
for iskit in 1 2 3 4; do
    if test -f kit${iskit}isdone; then
	run="$run $iskit"
    else
	todo="$todo $iskit"
    fi
done
case $todo in
    '')
	echo "You have run all your kits.  Please read README and then type Configure."
	chmod 755 Configure
	;;
    *)  echo "You have run$run."
	echo "You still need to run$todo."
	;;
esac
: Someone might mail this, so...
exit

INTERNET:  paul@devon.lns.pa.us        |      If life's a bitch, then
UUCP:      ...!rutgers!devon!paul      |      we must be her puppies.