Line discipline part 1 of 4

Dave Shepperd shepperd at dms.UUCP
Fri Nov 10 06:34:55 AEST 1989



# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by shepperd on Wed Nov  8 20:49:35 PST 1989
# Contents:  README README.UNIX cled.doc cledsetup.doc cled_ioctl.h
#	cled_structs.h cledefault.c master.awk mkcledc
 
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'
Cled version 1.7 11/07/89

If you have any comments and/or suggestions about this editor, feel free
to forward them to me (shepperd at dms.UUCP).

The installation procedure is automated for XENIX/386 and SCO UNIX systems
only. Although it has worked on a Xenix/286 system, there are A LOT of
changes required. I haven't yet received the list of changes from the guy
who did the port so I don't recommend 286 users bother with it just now.

The installation script edits the following files in /usr/sys/conf on Xenix:

	master	- adds cled in the discipline table
	link_xenix - adds the cled.o object file in the link command

and the following files in /etc/conf/pack.d/kernel on Unix:

	space.c

I HIGHLY RECOMMEND YOU BACKUP THESE FILES BEFORE BEGINNING. The awk procedures
assume things about the contents of these files, which may not be true in
all environments so it is conceivable that it could mess them up. If you
have out of the box SCO software and haven't edited those files yourself,
there shouldn't be a problem. If they do get messed up, your system
will NOT be destroyed. You can simply restore those files and remake the
kernel. The script makes a copy of the unmodified file(s) and reports the
name(s) of the copy(s) during the installation.

Also, on non-SCO Unix or Xenix/286 systems, this installation script will very
likely screw up. I suggest you either review it carefully before running it
or do the installation by hand (see install.unix for details).

Unpack the distribution into an empty directory. If the cledinst file
doesn't already have execute permission, set it. Login as root and type

	sh cledinst

or if using SCO UNIX:

	sh cledinst.unix

It'll ask you if you want to install or remove cled. If you have a version
that predates version 1.7, I suggest you select the remove option before
adding the new version. Select the add option and it'll install cled on your
system. You may add cled over and over without removing it. The script will
change only the things necessary to make the installation. If there were no
errors, it'll then ask if you want to rebuild the kernel and whether you
want the newly built kernel to boot by default. Answer the q's appropriately
and reboot the system. If cled installed correctly, there will have been no
error messages during the make sequence and when the system boots it'll
announce "cled version 1.x installed as line discipline n" on the console.

If you want to try out cled without installing it in the kernel, you can do
so by typing (you don't need to be root to do this):

	make cled

then typing:

	cled

which will put your terminal in raw mode and will run cled as a program. You
can type in stuff and use the cursor keys to edit the line and do the
history functions. This is basically a demo mode, the stuff you type in is
placed in the history buffer but otherwise ignored. Exit with an EOF (^D
unless you've mapped EOF to some other character). You might want to do this
until the key mapping defaults are set to your liking. You can edit
cledefault.c adjusting key mapping and stuff and remaking cled until you are
happy with the setup then install cled into the kernel.

After cled is installed in the kernel and the system rebooted, you can start
cled with a "stty line n" where n is the value displayed on the console
during boot (this is kinda icky), or you can run cledsetup (useful to call
it in your .login or .profile files) which will figure out the n
automagically and turn it on for you. Cledsetup also lets you dynamically
map the keys to the functions you prefer (the defaults are those found on
VMS). If it's turned on correctly, it'll announce same via a banner message
on your terminal (also gives the pid of the process that turned cled on as
well as the pid of its parent). It is possible for any process to turn cled
on/off on any terminal it has permission to issue an ioctl or stty, so the
banner is also sort of a tattle message ("Hey, so and so just screwed up
your terminal!").

Finally, if you have trouble with the installation and/or the instructions
you can contact me on voice-line at (408) 434-1711 10am-8pm PDT.

Manifest:

	README		- this file
	README.UNIX	- how to install on non-Xenix systems
	mkcledc		- mixes the cleda* files to cled.c
	cled.doc	- how cled works (more or less)
	cledsetup.doc	- how cledsetup works
	cledinst	- installation script for Xenix
	cledinst.unix	- installation script for SCO UNIX
	cled_ioctl.h	- misc defines needed by all the .c pgms
	cled_structs.h	- structure declarations needed by cled
				and cleddump (not used by cledsetup)
	cled.c		- the editor
	cledefault.c	- code that sets the defaults (you may want to edit
				this to set global defaults to match your
				preferences before doing the install).
	cleddump.c	- a debugging utility to dump cled structures
	cledsetup.c	- a keymapping utility
	makefile	- makefile for cled utilities
	makefile.unix	- makefile for Unix version
	master.awk	- awk program used to edit master
	space.c.awk	- awk program used to edit space.c (Unix version)
	space.c.rawk	- awk program used to remove cled from space.c

Site dependent compile time variables which you may want to change to suite
your needs can be found in cled_structs.h These variables will most
certainly have to be changed if you plan on running this code on Xenix/286.

	MAX_TTYBUFS - This value sets the maximum number of terminals that
			can run cled simultaneously. If you want everybody
			on your system to be able to run it, then you need
			to set this value to the sum of all the real,
			pseudo and virtual terminals that are defined on your
			system. (Default is 8). If this value is too low,
			then the system may run out and users will be
			denied use of cled. If the value is too high, then
			non-paged memory will be wasted (about 256 bytes
			per buffer).
			
	COMBUFSIZ - Sets the size in bytes of the working command line buffer.
			The default on 386 systems is 256.

	HISTBUFSIZ - This value sets the size in bytes of the history buffer.
			For 386 systems, the default is 1024. For 286 systems
			the default is 256. This parameter will have the biggest
			effect in consuming non-paged memory, especially on
			286 systems.

	PROMPTBFSIZ - Sets the size in bytes of the prompt buffer. The default
			on 386 systems is 80. The default on 286 systems is 16.

	MULTI_LB - This value (used as a boolean), if set non-zero, will enable
			code to assign a command/history buffer to every process
			that is attached to a tty which has cled enabled. This
			option is enabled by default on 386 systems and disabled
			by default on 286 systems. If disabled, there will be one
			history buffer per terminal shared among all processes
			that are using that terminal.

	MAX_LEDBUFS - This value is only significant if MULTI_LB is non-zero.
			It specifies how many command/history buffers are
			allocated to a pool. Whenever a process starts up and
			issues a read from a terminal, one of these led-bufs
			is taken from the pool. The working command line and
			the associated history buffer is located in one of these
			led_bufs. When the process is deleted, the buffer is
			placed back in the pool. Each led_buf is about 70 +
			COMBUFSIZ+PROMPTBUFSIZ+HISTBUFSIZ bytes in size. The
			default on 386 systems is 16. On 286 systems, the
			MULTI_LB defaults to 0, so there's one per tty_buf
			which is not adjustable other than changing
			MAX_TTYBUFS.

If you change these values, you'll need to remake cled and cleddump. I suggest
you reinstall cled (the installation procedure will figure out how much it has
to do).

Known problems with this release:

Occasionally, it seems to "forget" to print a prompt. This very
rarely happens and I've only noticed it after some process "broadcasts"
a message to the terminal at the same time or nearly the same time as the
a read is issued to the terminal by a different process. Anyway, the symptom
is that the terminal appears dead (or the system is busy) when actually it
is waiting for input. You can check it by typing anything (since chars are
echoed only if a read is pending, your keystrokes will be echoed if the
system expects input from your terminal) such as the refresh char, which
will repaint the line including the prompt.

Once in a blue moon, I've noticed the tty struct getting cleared (or at
least reset to boot-time values) as though some process issused a ttinit on
the port. This is not a polite thing to do to a working tty, and at this
time, I haven't a clue why it happens. Among the fields that get zapped is
the one indicating which line discipline it is supposed to use. When this
happens, effectively cled gets turned off but not cleanly as would do "stty
line 0" for example. I honestly don't believe this is a problem in cled
itself (hence, not my bug) because this has happened AFTER a read is started
on the terminal and cled has gone to sleep waiting for an interrupt. The
struct is not reset via an ioctl either (maybe there's some piece of code
somewhere that's not happy about having the line field in the tty struct
non-zero). Whenever it happened to me (hasn't happend to anyone else yet),
it happend just after exiting telnet, just after doing a su or after
starting a background job that sends messages to an X-server. Anyway, in an
effort to bandaid the problem, I put a timer in the read loop. If cled ever
wakes up and finds the tty struct different than it was when the read
started, it announces same on the terminal and restores the tty struct. This
will "fix" the problem if the struct gets blitzed while cled is in the
middle of a read, but if it happens while there is no read open, your
terminal will be left in raw mode with no echo and using line discipline 0.
P.S. I put this fix in around 7/5/89 and as of 11/07/89, have not had the
problem occur.

@//E*O*F README//
chmod u=rw,g=r,o=r README
 
echo x - README.UNIX
sed 's/^@//' > "README.UNIX" <<'@//E*O*F README.UNIX//'
What you have to do to install cled is two separate things: one is
install it as a device and the other is install it as a line discipline
(there're separate entry points in cled.c for both the driver and the
discipline). 

The procedure cledinst.unix is the one I use to install/de-install
cled from our SCO UNIX system. It may be readily adaptable to whatever
flavor of Unix you are using. Then again....

In some flavors of *nix there's a directory tree in /etc/conf that
has directories for the various devices on the system. Installing a
device basically involves assigning a major device number and installing
a directory in /etc/conf/pack.d named after the driver with the driver
code in it. There may be a automagic way to do this, then again there
may not. You may find the information required in your system's release
notes or in a "guide to writing device drivers" or some such.

In any case, there is not likely an automatic way to install
a line discipline. This has to be done the hard way. You need to edit
the space.c file in the /etc/conf/pack.d/kernel directory to add
cled in the line discipline table. You can look at the space.c.awk
file which "patches" the space.c file on SCO UNIX in the cledinst.unix
procedure for details  about what to put in the file. Anyway, the
code might look something like this before the patch:

struct linesw linesw[]=
{
/*0*/ ttopen, ttclose, ttread, ttwrite, ttioctl, ttin, ttout, nulldev,
        0
};
int	linecnt = 1;

Edit the file (or let awk do it) and make it look like this:

extern int cleopen(), cleclose(), cleread(), clewrite(), cleioctl(),
		 cleinput(), cleoutput();
struct linesw linesw[]=
{
/*0*/ ttopen, ttclose, ttread, ttwrite, ttioctl, ttin, ttout, nulldev,
/*1*/ cleopen, cleclose, cleread, clewrite, cleioctl, cleinput, cleoutput, nulldev,
        0
};
int	linecnt = 2;

You'll need to do this patch everytime you install a new link kit (since it'll
replace the space.c with a new one). You shouldn't have to do this otherwise.

Make a new kernel. Boot the new kernel. Login and type stty line n where
n is the number cled reported at boot time or run cledsetup.

Good luck. Let me know how it works out.
@//E*O*F README.UNIX//
chmod u=rw,g=r,o=r README.UNIX
 
echo x - cled.doc
sed 's/^@//' > "cled.doc" <<'@//E*O*F cled.doc//'
To make a standalone version (used to debug the editor itself):

   	make cled

To make a line discipline version:

   	(as root)
	sh cledinst	   (Xenix)
	sh cledinst.unix   (Unix)

Minimum System requirements to install this editor:
   1) Be able to login as root.
   2) SCO UNIX, Xenix/386 2.3.1, Xenix/286 2.2.1 or later.
   3) Unix/Xenix development system.
   4) The link kit must be installed.

Minimum requirements to use this editor:
   1) VT100 terminals (or compatibles) connected either directly or
	through terminal servers or X window system servers running xterm.

The editor interprets input escape sequences using the ANSI standard (i.e.
those used by VT100 and compatible terminals) for the keypad and arrow keys.
This is not easily changed by the uninitiated, however, you may define
cursor motion functions to control keys rather than arrow keys via startup
code. The output escape sequences may be set by startup code.

Features (or bugs or warts depending on your point of view):

There are 18 editor primitives which are:
	toggle insert/overstrike mode
	skip to beginning of line
	skip to end of line
	delete char to left of cursor
	delete char under cursor
	delete "word" to left of cursor
	delete "word" to right of cursor
	delete from cursor to beginning of line
	delete from cursor to end of line
	move cursor left one char
	move cursor right one char
	repaint line
	recall previous line
	recall next line
	find (next) matching line
	newline
   	"escape" the next character
	purge all typeahead (crosses newlines)

Each primitive is (optionally) assigned to a control key and/or a terminal
function key (such as up-arrow or PF4). Which function (if any) assigned to
which key is user selectable (via an ioctl or through an ascii file which a
setup program will read at startup). Any key not assigned to one of those
primitives (except null, VINTR and VQUIT), is inserted into the command line
at the cursor.

Briefly, how it interfaces the user with the system:

This editor has two parts which are independent of one another. One is a
line discipline and the other is a character device. The device has ioctl
functions defined that can be used by a setup program to get details about
the discipline such as its number, how big compile time parameters are, etc.
The discipline part is the editor but it also has ioctls defined that can be
used to turn it on and off as well as assigning keys, output escape
sequences and the text of some messages that can be displayed by the
interrupt and eof chars as well as the default edit mode (insert/overstrike)
and screen width (80/132). The editor can be turned on and off with the stty
command and/or ioctls from within a running program. It also turns itself
off while the terminal is set to "raw" mode (CLED defines "raw" mode as
having any of the tty bits ECHO, ECHOE, ECHOK or CANON clear; that is, all
four bits must be set before cled will edit any input). If cled senses
raw mode, it passes all control to line discipline 0, so the line edits
if any, are done as though cled were not in the loop. This also means that
input during raw mode is not placed in the history buffer.

Since the editor is implemented as a line discipline, it is not tied to
any particular program or shell. It does not fork a process nor does it
insert an additional layer of processing that isn't already called for
with discipline 0 (if terminal data is to be "cooked", cled does the
cooking instead of discipline 0). It does NOT replace any "off-line"
editing that your programs or shells might have (i.e. the command line
editing of csh or ksh will work the same whether CLED is running
or not). If your terminal is communicating via a stream driver, then
cled is not likely to work since streams devices don't use this method
of line discipline.

Command line history functions:
   	The history buffer is a fixed size for each process. Its size is
	set at compile time. It is not dynamically allocated
	because there's limited non-paged pool (VMS terminology) and no
	process quotas. At this time, I'm not sure how to enforce process
	quotas so I just made the buffer size fixed. To conserve space,
   	recalled commands entered unchanged are moved to the
   	head of the buffer as are commands entered that match
   	existing entries in the history buffer. That is, there won't be
   	multiple occurrences of exactly the same command in the
   	history buffer. There is one of these buffers assigned
   	from a pool for each process that establishes a stream
   	to the terminal. (I.e., you will have a different history
   	buffer for each application that is forked from the shell unless
	the compile time options are set to force one buffer per terminal.)

	recall previous line: normally assigned to up-arrow, puts the
		next line in the history buffer on the command line
		replacing whatever is there. If there are no more lines
		in the history buffer (i.e. you scrolled off the top)
		a null line will be brought up.
	recall next line: normally assigned to down-arrow, puts the
		command that followed the one currently on the command 
		line. This is only useful if you've preceded it with
		some up-arrows, because scrolling off the bottom of the
		history buffer results in a blank line.
        find (next) matching line: Type some chars on the command line
		(such as vi, m or cc), then type the char you've assigned
		to this primitive and cled will find the most recent command
		in the history buffer that matches. If you make no changes
		to the command line and type the assigned char again,
		cled will find the next youngest matching command and so on.
		It echoes a bell if there are no more matching strings.

Command line prompts:
   	cled attempts to determine a prompt string by capturing in a buffer
   	text written to the terminal from the process that last did a 
	read. The buffer is
   	sent to the terminal and cleared when a CR or LF is seen.
   	If a read is issued to the terminal, then the contents of the
   	prompt buffer are displayed followed by an escape sequence to
   	erase the display to end of line.
	Sometimes it screws up and doesn't get it right, but it is no
	worse than the way the system works without it.

The behavior of this discipline will certainly be foreign to many Unix users
since it is one of very few that doesn't echo characters as they are typed.
Instead, typeahead is saved in a buffer and echoed only after a read is
issued to the terminal (this is the behavior of the VMS and MS-DOS terminal
drivers). I didn't necessarily design it this way, but instead it fell out
of the cracks due to the fact that the editor itself runs at task time
rather than at interrupt time and it is responsible for echo (discipline 0
echoes at interrupt time). Technically, the editor could be run at interrupt
time, but I believe this would be a bad idea from the system's point of view.

This discipline tries to be "helpful" and recognize when your command line
gets messed up by a "broadcast" message. That is, when some other process
sends some text to your terminal while your typing in a command (or waiting
at a prompt). When this happens, it'll clear the current line, display the
broadcast message and repaint the command line. There's a 1/10 second delay
between the broadcast message and repaint.

Some implementation details:
cled uses discipline 0 to do everything it doesn't know how to do or doesn't
want to do. This includes virtually all the output character processing.
The editor working text buffer was assumed to be a contiguous array of chars
when it was designed (in the early 80's) and I just wrapped Xenix driver
code around it. As such, it doesn't use the canq clist for the input text 
as does discipline 0 and this would be quite difficult to fix. The
consequence of this is that utilities that peek and/or poke into the
canq clist won't have the desired effect. The ttrdchk() driver function
looks at either t_delct, t_rawq or t_canq fields depending on the states
of various bits in t_state and t_lflag in order to report (true or false)
whether there's typeahead pending. cled updates the t_delct field when
appropriate and uses the t_rawq to store normal typeahead so most of the
time typeahead test functions will work properly (i.e., the crtl function
rdchk()). I didn't, however, test all permutations of the various rdchk()
options, so I can't say that they'll all work as expected.
@//E*O*F cled.doc//
chmod u=rw,g=r,o=r cled.doc
 
echo x - cledsetup.doc
sed 's/^@//' > "cledsetup.doc" <<'@//E*O*F cledsetup.doc//'
Name

	cledsetup - Turn on cled and set key mapping

Syntax

	cledsetup [-o output_file] [input_file]

Description

cledsetup turns on cled and optionally sets keyboard mapping to the cled
edit functions and/or creates an output file with the current key map. If an
output file is specified, it is created with the current key mappings before
any of them are changed and the format is such that it can be fed as input
to cledsetup so one can "temporarily" change the key mapping. The default
input filename is .cledrc and the following paths are searched for the file
in the following order: ./, $CLED/ or $HOME/. No error will be reported if
no file is found.

The input file format consists of a collection of ascii lines where each
line specifies either a single mode, key or string sequence. Lines are
delimited with the newline character (\n). The first token on the line must
be one of "mode", "key" or "string" to set mode, keymap and string sequence
respectively. The best examples can be obtainted by selecting the -o option
and inspecting (or editing) the resulting output file. To summarize:

    mode modename
    key keyname edit_function
    string stringname "text"

Any mode or key can be set without affecting the state of any other mode or
key, however, if any string is set (within a single invocation of
cledsetup), all strings will be first set to their default values then the
one(s) that require changing will be changed.

modenames:

    80 - 80 column mode
    132 - 132 column mode
    insert - insert editing
    overstrike - overstrike editing

keynames description (input char(s) cled uses to identify key):

    up - up arrow (\033[A)
    down - down arrow (\033[B)
    right - right arrow (\033[C)
    left - left arrow (\033[D)
    enter - keypad enter (\033OM)
    pf1 - keypad pf1 (\033OP)
    pf2 - keypad pf2 (\033OQ)
    pf3 - keypad pf3 (\033OR)
    pf4 - keypad pf4 (\033OS)
    comma - keypad comma (\033Ol)
    minus - keypad minus (\033Om)
    period - keypad period (\033On)
    0 - keypad 0 (\033Op) [aka kp0]
    1 - keypad 1 (\033Oq) [aka kp1]
    2 - keypad 2 (\033Or) [aka kp2]
    3 - keypad 3 (\033Os) [aka kp3]
    4 - keypad 4 (\033Ot) [aka kp4]
    5 - keypad 5 (\033Ou) [aka kp5]
    6 - keypad 6 (\033Ov) [aka kp6]
    7 - keypad 7 (\033Ow) [aka kp7]
    8 - keypad 8 (\033Ox) [aka kp8]
    9 - keypad 9 (\033Oy) [aka kp9]
    del - delete key (\177) [aka DEL]
    ctl_@ - control @ (\000) [aka null]
    ctl_a - control A (\001)
    ...b-y - control B thru Y (\002 - \031)
    ctl_z - control Z (\032)
    ctl_[ - control [ (\033) [aka esc]
    ctl_\ - control \ (\034)
    ctl_] - control ] (\035)
    ctl_^ - control ^ (\036)
    ctl__ - control _ (\037)
    end - "end" (\033[E or \033[4~)
    page_up - "page up" (\033[F or \033[5~)
    page_down - "page down" (\033[G or \033[6~)
    home - "home" (\033[H or \033[3~)
    insert - "insert" (\033[I or \033[2~)
    f1 - F1 (\033[11~)
    f3 through f5 - F2 through F5 (\033[12~ through \033[15~)
    f6 through f10 - F6 through F10 (\033[17~ through \033[21~)
    f11 through f14 - F11 through F14 (\033[23~ through \033[26~)
    f15 and f16 - F15 and F16 (\033[28~ and \033[29~)
    f17 through f20 - F17 through F20 (\033[31~ through \033[34~)

edit_function names and their descriptions:

    insert - select insert mode
    overstrike - select overstrike mode
    goto_bol - go to beginning of line
    goto_eol - go to end of line
    del_word_left - delete the "word" to the left of cursor
    del_word_right - delete the "word" to the right of cursor
    del_to_bol - delete from cursor to beginning of line
    del_to_eol - delete from cursor to end of line
    cursor_left - move cursor left 1 char
    cursor_right - move cursor right 1 char
    del_char_left - delete the char to the left of cursor
    del_char_right - delete the char under the cursor
    refresh - reprint the current line
    previous - get previous command from history buffer
    next - get next command from history buffer
    find - find (next) matching sequence in history buffer
    newline - terminate current line and send to program
    superquote - quote the following character
    132_80 - toggle between 80 column and 132 column mode
    nop - do nothing. Eat the char.
    advance - set direction to forward
    backup - set direction to reverse
    skip_word - skip word using current direction
    skip_char - skip char using current direction
    skip_line - skip line using current direction
    bell - ring bell but otherwise eat char
    skip_word_right - skip over "word" to right of cursor
    skip_word_left - skip over "word" to left of cursor
    skip_to_xol - skip to eol/bol using current direction
    purge - delete all typeahead and clear current line

stringnames and descriptions (char sequences required to make terminal do task):

    up - move cursor up 1 line
    clreol - erase from cursor to end of line
    clrline - erase from cursor to beginning of line
    setinv - set inverse video
    setnorm - set normal video
    save - save current cursor attributes
    restore - restore saved cursor attributes
    msgeof - message to display when eof char is input
    msgintr - message to display when intr char is input
    msgquit - message to display when quit char is input
    setup - text to output to terminal when cled is turned on
    80col - switch to 80 column display
    132col - switch to 132 column display

The "text" can be any string enclosed in double quotes with the normal C
syntax for string constants.

@//E*O*F cledsetup.doc//
chmod u=rw,g=r,o=r cledsetup.doc
 
echo x - cled_ioctl.h
sed 's/^@//' > "cled_ioctl.h" <<'@//E*O*F cled_ioctl.h//'
#define ANSI_UP		0
#define ANSI_UP_STR		"\033[A"	/* up-arrow */
#define ANSI_CLREOL	1
#define ANSI_CLREOL_STR		"\033[0K"	/* clear to eol */
#define ANSI_CLRLINE	2
#define ANSI_CLRLINE_STR	"\r\033[0K"	/* clear whole line */
#define ANSI_SETINV	3
#define ANSI_SETINV_STR		"\033[7m"	/* set inverse video */
#define ANSI_SETNORM	4
#define ANSI_SETNORM_STR	"\033[0m"	/* set normal video */
#define ANSI_SAVE	5
#define ANSI_SAVE_STR		"\0337"		/* save cursor pos and attr's */
#define ANSI_RESTORE	6
#define ANSI_RESTORE_STR	"\0338"		/* restore cursor pos and attr's */
#define ANSI_MSGEOF	7
#define ANSI_MSGEOF_STR		"*EOF*\r\n"	/* EOF message */
#define ANSI_MSGINTR	8
#define ANSI_MSGINTR_STR	"\r\n*INTR*\r\n" /* INTR message */
#define ANSI_MSGQUIT	9
#define ANSI_MSGQUIT_STR	"\r\n*QUIT*\r\n" /* QUIT message */
#define ANSI_SETUP	10
#define ANSI_SETUP_STR		"\033<\033="	/* set terminal to app mode */
#define ANSI_80COL	11
#define ANSI_80COL_STR		"\033[?3l"	/* set to 80 cols */
#define ANSI_132COL	12
#define ANSI_132COL_STR		"\033[?3h"	/* set to 132 cols */
#define ANSI_COUNT	13		/* last one indicates total */

struct cle_stats {
   int ledbufs;		/* max number of led_buffers */
   int ttybufs;		/* max number of tty_buffers */
   int histsize;	/* size of history buffer */
   int promptsize;	/* size of prompt buffer */
   int combufsiz;	/* size of command buffer */
   int multi_lb;	/* t/f flag indicating multi-lb mode */
   int spt;		/* t/f flag indicating using sptalloc */
   int ansisize;	/* max length of all ascii strings */
   int ledbufs_used;	/* number of led_buf's in use */
   int ttybufs_used;	/* number of tty_buf's in use */
   int line;		/* cled's line discipline number */
   char vers[4];	/* version # */
};

struct cle_buf {
    struct led_buf *lbbase;
    struct led_buf *lbfree;
    struct tty_buf *tbbase;
    struct tty_buf *tbused;
    struct tty_buf *tbfree;
    struct proc *procbase;
    int lbsize;
    int tbsize;
};

/* The following structure is passed to the ioctl routine to /dev/cled
 * to assign the key bindings and the ANSI sequences (and other strings)
 * desired for various functions.
 *
 * If the ioctl completes with an error, then the len fields of the 
 * struct will have been changed to an index into the respective buffer
 * at which the error occured (the driver sets the value).
 *
 * The key buffer immediately follows the set_key struct and the
 * ANSI buffer immediately follows the key buffer.
 *
 * The key buffer contains pairs of chars; the first is the key number
 * and the second is the function number. The kdbuf_len entry in the
 * set_key struct contains the total number of these pairs of chars.
 * Any of the control keys and/or keypad keys can be set to any function
 * at any time. New definitions replace previous definitions. Keys not
 * explicitly defined in the buffer are left defined to whatever they
 * were.
 *
 * The ANSI buffer consists of a stream of null terminated strings
 * preceeded by the number of the sequence to which the string belongs.
 * If any ANSI sequence is defined, then ALL the sequences are first
 * reset to their defaults and then replaced with the new definitions.
 * That is, you can change one or all, but unlike the key definitions,
 * you cannot change just one without affecting all the others.
 */

struct set_key {
   int kdbuf_len;	/* key buffer length (in items) */
   int ansibuf_len;	/* length of ANSI definitions (in chars) */
   int modes;		/* default mode bits */
};

#define LDIOC  ('D'<<8)
#define LDGETS (LDIOC|16)	/* get cled stats */
#define LDGETBF (LDIOC|17)	/* get keydef buffers */
#define LDSETBF (LDIOC|18)	/* set keydef buffers */
#define LDGETB (LDIOC|19)	/* dump its guts (debug mode only) */
#define LDGETTTY (LDIOC|20)	/* dump a tty struct (debug mode only) */
#define LDGETC (LDIOC|21)	/* dump contents of a clist (debug only) */
#define LDGETHB (LDIOC|22)	/* get history buffer */
#define LDSETHB (LDIOC|23)	/* set history buffer */

/* Error codes returned from ioctl functions */

#define ERR_NOTTYBUF	128	/* no more ttybufs available */
#define ERR_NOLEDBUF	129	/* no more ledbufs available */
#define ERR_NOLBASS	130	/* no led buf assigned to process */
#define ERR_BADPARAM	131	/* bad paramater value */
#define ERR_BADIOCTL	132	/* bad ioctl function */

/* Editor functions: (don't change the order of these) */

#define CLEFUN_CHAR	0x00	/* insert character into buffer (default) */
#define CLEFUN_INSERT	0x01	/* toggle insert/overstrike mode */
#define CLEFUN_GOTOBOL	0x02	/* goto beginning of line */
#define CLEFUN_GOTOEOL	0x03	/* goto end of line */
#define CLEFUN_DELWLFT	0x04	/* delete word to left of cursor */
#define CLEFUN_DELWRIT	0x05	/* delete word to right of cursor */
#define CLEFUN_DELBOL	0x06	/* delete from cursor to beginning of line */
#define CLEFUN_DELEOL	0x07	/* delete from cursor to end of line */
#define CLEFUN_CURSL	0x08	/* move cursor left 1 position */
#define CLEFUN_CURSR	0x09	/* move cursor right 1 position */
#define CLEFUN_DELCLFT	0x0A	/* delete char left of cursor */
#define CLEFUN_DELCRIT	0x0B	/* delete char under cursor */
#define CLEFUN_REFRESH	0x0C	/* reprint the current line */
#define CLEFUN_PREVIOUS	0x0D	/* recall previous command */
#define CLEFUN_NEXT	0x0E	/* recall next command */
#define CLEFUN_FIND	0x0F	/* find matching string */
#define CLEFUN_NEWLINE	0x10	/* end of line */
#define CLEFUN_ESCAPE	0x11	/* "escape" the next character */
#define CLEFUN_132	0x12	/* toggle between 80 col and 132 col */
#define CLEFUN_NOP	0x13	/* nop */
#define CLEFUN_ADVANCE	0x14	/* set direction forward */
#define CLEFUN_BACKUP   0x15    /* set direction backward */
#define CLEFUN_SKIPW    0x16	/* skip word (per direction) */
#define CLEFUN_SKIPC	0x17	/* skip char (per direction) */
#define CLEFUN_SKIPL	0x18 	/* skip line (per direction) */
#define CLEFUN_BELL	0x19	/* ring bell */
#define CLEFUN_SKIPWL	0x1A	/* skip word left */
#define CLEFUN_SKIPWR	0x1B	/* skip word right */
#define CLEFUN_SKIPTOL	0x1C	/* skip to bol or eol per direction */
#define CLEFUN_PURGE	0x1D	/* purge all typeahead */
#define CLEFUN_MAX	0x1E	/* number of functions */

/* Key definitions: */

#define CLEKEY_NULL	0x00	/* null */
#define CLEKEY_CTLA	0x01	/* control A */
#define CLEKEY_CTLB	0x02	/* control B */
#define CLEKEY_CTLC	0x03	/* control C */
#define CLEKEY_CTLD	0x04	/* control D */
#define CLEKEY_CTLE	0x05	/* control E */
#define CLEKEY_CTLF	0x06	/* control F */
#define CLEKEY_CTLG	0x07	/* control G (bell) */
#define CLEKEY_CTLH	0x08	/* control H (backspace) */
#define CLEKEY_CTLI	0x09	/* control I (tab) */
#define CLEKEY_CTLJ	0x0A	/* control J (line feed) */
#define CLEKEY_CTLK	0x0B	/* control K */
#define CLEKEY_CTLL	0x0C	/* control L (form feed) */
#define CLEKEY_CTLM	0x0D	/* control M (carriage return) */
#define CLEKEY_CTLN	0x0E	/* control N */
#define CLEKEY_CTLO	0x0F	/* control O */
#define CLEKEY_CTLP	0x10	/* control P */
#define CLEKEY_CTLQ	0x11	/* control Q (xon) */
#define CLEKEY_CTLR	0x12	/* control R */
#define CLEKEY_CTLS	0x13	/* control S (xoff) */
#define CLEKEY_CTLT	0x14	/* control T */
#define CLEKEY_CTLU	0x15	/* control U (usually kill) */
#define CLEKEY_CTLV	0x16	/* control V (super quote on some systems) */
#define CLEKEY_CTLW	0x17	/* control W */
#define CLEKEY_CTLX	0x18	/* control X */
#define CLEKEY_CTLY	0x19	/* control Y */
#define CLEKEY_CTLZ	0x1A	/* control Z */
#define CLEKEY_CTLa	0x1B	/* control [ (escape) */
#define CLEKEY_CTLb	0x1C	/* control \ */
#define CLEKEY_CTLc	0x1D	/* control ] */
#define CLEKEY_CTLd	0x1E	/* control ~ */
#define CLEKEY_CTLe	0x1F	/* control ? */
#define CLEKEY_UP	0x20	/* up arrow */
#define CLEKEY_DOWN	0x21	/* down arrow */
#define CLEKEY_RIGHT	0x22	/* right arrow */
#define CLEKEY_LEFT	0x23	/* left arrow */
#define CLEKEY_ENTER	0x24	/* keypad enter */
#define CLEKEY_PF1	0x25	/* PF1 */
#define CLEKEY_PF2	0x26	/* PF2 */
#define CLEKEY_PF3	0x27	/* PF3 */
#define CLEKEY_PF4	0x28	/* PF4 */
#define CLEKEY_KPCOMMA	0x29	/* KP comma */
#define CLEKEY_KPMINUS	0x2A	/* KP minus */
#define CLEKEY_DOT	0x2B	/* KP period */
#define CLEKEY_KP0	0x2C	/* KP 0 */
#define CLEKEY_KP1	0x2D	/* KP 1 */
#define CLEKEY_KP2	0x2E	/* KP 2 */
#define CLEKEY_KP3	0x2F	/* KP 3 */
#define CLEKEY_KP4	0x30	/* KP 4 */
#define CLEKEY_KP5	0x31	/* KP 5 */
#define CLEKEY_KP6	0x32	/* KP 6 */
#define CLEKEY_KP7      0x33    /* KP 7 */
#define CLEKEY_KP8	0x34	/* KP 8 */
#define CLEKEY_KP9	0x35	/* KP 9 */
#define CLEKEY_DEL	0x36	/* delete */
#define CLEKEY_HOME	0x37	/* home key */
#define CLEKEY_END	0x38	/* end key */
#define CLEKEY_INSERT	0x39	/* insert key */
#define CLEKEY_PGUP	0x3A	/* page up key */
#define CLEKEY_PGDN	0x3B	/* page down key */
#define CLEKEY_F1	0x3D	/* F key */
#define CLEKEY_F2	0x3E	/* F key */
#define CLEKEY_F3	0x3F	/* F key */
#define CLEKEY_F4	0x40	/* F key */
#define CLEKEY_F5	0x41	/* F key */
#define CLEKEY_F6	0x42	/* F key */
#define CLEKEY_F7	0x43	/* F key */
#define CLEKEY_F8	0x44	/* F key */
#define CLEKEY_F9	0x45	/* F key */
#define CLEKEY_F10	0x46	/* F key */
#define CLEKEY_F11	0x47	/* F key */
#define CLEKEY_F12	0x48	/* F key */
#define CLEKEY_F13	0x49	/* F key */
#define CLEKEY_F14	0x4A	/* F key */
#define CLEKEY_F15	0x4B	/* F key */
#define CLEKEY_F16	0x4C	/* F key */
#define CLEKEY_F17	0x4D	/* F key */
#define CLEKEY_F18	0x4E	/* F key */
#define CLEKEY_F19	0x4F	/* F key */
#define CLEKEY_F20	0x50	/* F key */
#define CLEKEY_MAX	0x51	/* size of key defines */

/* default modes */

#define CLEMODE_INSERT	0x01	/* insert mode */
#define CLEMODE_OVER    0x02	/* overstrike mode */
#define CLEMODE_80	0x04	/* 80 column mode */
#define CLEMODE_132	0x08	/* 132 column mode */

@//E*O*F cled_ioctl.h//
chmod u=rw,g=r,o=r cled_ioctl.h
 
echo x - cled_structs.h
sed 's/^@//' > "cled_structs.h" <<'@//E*O*F cled_structs.h//'
#include "cled_ioctl.h"

/*********************************************************************************
 * The following #defines set the configuration parameters for cled. You may need
 * or want to adjust them to suit the requirements specific to your system. This is
 * especially true on a 286 system since it has very limited data space.
 *******************************************************************************/

#define MAX_TTYBUFS 	24	/* max number of tty and pty ports */
#ifdef M_I386
#define MAX_LEDBUFS 	32	/* max number of history buffers */
#define HISTBUFSIZ	1024	/* size of history/keydef buffer */
#define PROMPTBFSIZ	80	/* max # of chars to keep for prompt */
#define COMBUFSIZ	256	/* size of command line buffer */
#define MULTI_LB	1	/* set to true if desire separate history per process */
#define _SPTALLOC	1	/* 386 has sptalloc() and sptfree() */
#else
#define HISTBUFSIZ	256	/* 286 has limited data space... */
#define PROMPTBFSIZ	16	/* ...so make these smaller */
#define COMBUFSIZ	134
#define MULTI_LB	0	/* separate history per terminal rather than per process */
#define _SPTALLOC	0	/* 286 has no sptalloc */
#endif

#if !(_SPTALLOC)
#define ANSISIZE	128	/* max length of all user defined ansi strings */
#endif

/************ End of user adjustable paramters **********************************/

#define VERSION "1.7"		/* current cled version */
#ifndef M_KERNEL		/* if standalone mode... */
#undef MAX_TTYBUFS
#ifdef MAX_LEDBUFS
#undef MAX_LEDBUFS
#endif
#define MAX_LEDBUFS	1	/* ...only 1 tb and 1 lb */
#define MAX_TTYBUFS	1
#undef MULTI_LB
#undef _SPTALLOC
#define MULTI_LB	0	/* ...and no multi-buffers */
#define _SPTALLOC	0	/* ...or sptalloc() */
#if !defined(ANSISIZE)
#define ANSISIZE	128
#endif
#endif

#if !(MULTI_LB)
#ifdef MAX_LEDBUFS
#undef MAX_LEDBUFS
#endif
#define MAX_LEDBUFS MAX_TTYBUFS		/* one lb per tb if not multi_lb mode */
#endif

#define LD_DONE	    0x0001	/* flag indicating read complete */
#define LD_QUIT	    0x0002	/* completed under QUIT char */
#define LD_INTR     0x0004	/* completed under INTR char */
#define LD_EOF	    0x0008	/* completed under EOF */
#define LD_DIRTY    0x0010	/* command buffer has been changed */
#define LD_INSERT   0x0020	/* insert mode */
#define LD_BACKUP   0x0040	/* direction bit (0=advance,1=backup) */
   				/* if last flag >= 0x10000, change led_buf.flags
   				   from a short to a long */
#define TB_NOLINE   0x0001	/* not using this discipline */
#define TB_OPEN	    0x0002	/* tty buff is open */
#define TB_READING  0x0004	/* read currently in progress */
#define TB_WRITING  0x0008	/* write currently in progress */
#define TB_INSERT   0x0010	/* insert/overstrike default (set = insert mode) */
#define TB_132	    0x0020	/* 132 column mode */
#define TB_OVERUN   0x0040	/* input buffer overrun */
#define TB_OPENING  0x0080	/* tty buf is opening */
#define TB_FLUSHIT  0x0100	/* flush the input que */
/* if last flag is greater than 0x8000, change flags from short to long */

#ifdef M_I386
#pragma pack(1)
#endif
struct led_buf {
#if MULTI_LB		 /* linked lists if separate history buffers */
   struct led_buf *next; /* pointer to next structure in chain */
   struct led_buf *last; /* pointer to previous structure in chain */
   struct proc *proc;	/* ptr to proc struct assigned to this lb */
#endif
   struct tty_buf *ttybf; /* ptr to ttybuf */
   unsigned char *bufend; /* ptr to end of working command buffer */
   unsigned char *owed;	/* ptr to string owed */
   unsigned char *lcurs; /* left cursor postion */
   unsigned char *rcurs; /* right cursor postion */
   unsigned char *key;	/* ptr to mapstr definition buffer */
   int maxlin;		/* max length of input */
   int oldndx;		/* index into old com area for recall */
   int oldmatlen;	/* length of match string entered */
   int indx;
   short flags;		/* ld flags */
#if MULTI_LB
   short pid;		/* pid assigned to this lb */
   short ppid;		/* ppid of proc assigned to this lb */
#endif
   short c_posn;	/* terminal cursor column address */
   short end_posn;	/* terminal eol column address */
   short state;		/* current state */
   unsigned short keynum; /* function key number */
   unsigned char buf[COMBUFSIZ]; /* working command buffer */
   unsigned char prmpt[PROMPTBFSIZ]; /* prompt string held here */
   unsigned char old[HISTBUFSIZ];  /* command history located in this buffer */
   unsigned char c;	/* current char */
   unsigned char defkey;  /* flag used for definig keys */
   unsigned char prmptsz; /* length of prompt string */
};
#ifdef M_I386
#pragma pack()
#endif

struct tty_buf {
   struct tty_buf *next;		/* bufs are stored in linked list */
   struct tty_buf *last;		/* doubly linked for speed search */
   struct led_buf *lbtop;		/* ptr to top of lb chain using this tty */
   struct tty *ttyp;			/* tty attached to this tty_buf */
   ushort iflag;			/* copy of tty flags at start of read */
   ushort oflag;
   ushort lflag;
   ushort cflag;
   char cc[NCC+2];
   unsigned char keymap[CLEKEY_MAX];	/* key mappings */
   unsigned char *ansi[ANSI_COUNT];	/* place for escape sequence ptrs */
#if _SPTALLOC
   unsigned char *tmpbuf;		/* temp buffer ptr */
#else
   unsigned char tmpbuf[ANSISIZE];	/* space for ansi strings */
#endif
   int tmpsize;				/* temp buffer size */
   struct clist broadcast;		/* place to hold broadcast messages */
   unsigned short flags;		/* flags associated with this tty */
   char f_refresh;			/* .ne. if to refresh */
   char f_sleep_read;			/* .ne. if sleeping on read */
};

#if _SPTALLOC && defined(M_KERNEL)
#  if defined(M_UNIX)
   	extern caddr_t *sptalloc(int pages,int mode,int base,int flag);
   	extern void sptfree(char *va,int npages,int freeflag);
#       define Sptalloc(bytes) sptalloc(btoms(bytes),PG_P,0,0)
#	define Sptfree(addr,bytes) sptfree(addr,btoms(bytes),1)
#  else
#	define Sptalloc(bytes) sptalloc(bytes)
#	define Sptfree(addr,bytes) sptfree(addr,bytes,1)
#  endif
#else
#  if !defined(M_KERNEL)
#	define Sptalloc(size) malloc(size)
#	define Sptfree(addr,size) free(addr)
#  endif
#endif
@//E*O*F cled_structs.h//
chmod u=rw,g=r,o=r cled_structs.h
 
echo x - cledefault.c
sed 's/^@//' > "cledefault.c" <<'@//E*O*F cledefault.c//'

/***********************************************************************************
 * Set the keymap to defaults.
 */
    	static int setup_key_defaults(tbp)
        struct tty_buf *tbp;
/*
 * At entry:
 *	tbp - ptr to tty_buf into which to set the defaults
 * At exit:
 *	keymap initialised in struct 
 */
{
    int cnt;
    char *chr;
    for (chr = tbp->keymap,cnt = 0; cnt<CLEKEY_MAX; ++cnt) {
	*chr++ = CLEFUN_CHAR;			/* default all keys to simply insert in buf */
    }
    tbp->keymap[CLEKEY_NULL] = CLEFUN_ESCAPE;	/* escape char */
    tbp->keymap[CLEKEY_CTLA] = CLEFUN_INSERT;	/* toggle insert/overstrike mode */
    tbp->keymap[CLEKEY_CTLB] = CLEFUN_GOTOBOL;	/* goto bol */
    tbp->keymap[CLEKEY_CTLE] = CLEFUN_GOTOEOL;	/* goto eol */
    tbp->keymap[CLEKEY_CTLF] = CLEFUN_FIND;	/* find string */
    tbp->keymap[CLEKEY_CTLH] = CLEFUN_GOTOBOL;	/* goto bol */
    tbp->keymap[CLEKEY_CTLJ] = CLEFUN_DELWLFT;	/* dele word left */
    tbp->keymap[CLEKEY_CTLM] = CLEFUN_NEWLINE;	/* eol */
    tbp->keymap[CLEKEY_CTLR] = CLEFUN_REFRESH;	/* repaint */
    tbp->keymap[CLEKEY_CTLU] = CLEFUN_DELBOL;	/* dele to bol */
    tbp->keymap[CLEKEY_CTLW] = CLEFUN_132;	/* toggle 80/132 mode */
    tbp->keymap[CLEKEY_CTLX] = CLEFUN_PURGE;	/* dele everything */
    tbp->keymap[CLEKEY_UP] = CLEFUN_PREVIOUS;	/* up arrow */
    tbp->keymap[CLEKEY_DOWN] = CLEFUN_NEXT;	/* down arrow */
    tbp->keymap[CLEKEY_LEFT] = CLEFUN_CURSL;	/* left arrow */
    tbp->keymap[CLEKEY_RIGHT] = CLEFUN_CURSR;	/* right arrow */
    tbp->keymap[CLEKEY_PF1] = CLEFUN_BELL;	/* no gold, ring bell to remind me */
    tbp->keymap[CLEKEY_PF2] = CLEFUN_BELL;	/* nothing */
    tbp->keymap[CLEKEY_PF3] = CLEFUN_FIND;	/* find string (same as ^F) */
    tbp->keymap[CLEKEY_PF4] = CLEFUN_DELEOL;	/* dele to eol */
    tbp->keymap[CLEKEY_KPMINUS] = CLEFUN_DELWRIT; /* del word right */
    tbp->keymap[CLEKEY_KPCOMMA] = CLEFUN_DELCRIT; /* del char under cursor */
    tbp->keymap[CLEKEY_ENTER] = CLEFUN_NEWLINE;	/* eol */
    tbp->keymap[CLEKEY_DOT] = CLEFUN_BELL;	/* nothing */
    tbp->keymap[CLEKEY_KP0] = CLEFUN_SKIPL;	/* skip line per direction bit */
    tbp->keymap[CLEKEY_KP1] = CLEFUN_SKIPW;	/* skip word per direction bit */
    tbp->keymap[CLEKEY_KP2] = CLEFUN_SKIPTOL;	/* goto eol or bol per direction bit */
    tbp->keymap[CLEKEY_KP3] = CLEFUN_SKIPC;	/* skip char per direction bit */
    tbp->keymap[CLEKEY_KP4] = CLEFUN_ADVANCE;	/* set direction forward */
    tbp->keymap[CLEKEY_KP5] = CLEFUN_BACKUP;	/* set direction backward */
    tbp->keymap[CLEKEY_KP6] = CLEFUN_BELL;	/* key does nothing */
    tbp->keymap[CLEKEY_KP7] = CLEFUN_BELL;	/* key does nothing */
    tbp->keymap[CLEKEY_KP8] = CLEFUN_BELL;	/* key does nothing */
    tbp->keymap[CLEKEY_KP9] = CLEFUN_BELL;	/* key does nothing */
    tbp->keymap[CLEKEY_DEL] = CLEFUN_DELCLFT;	/* delete char to the left */
    tbp->keymap[CLEKEY_HOME] = CLEFUN_GOTOBOL;	/* goto begininning of line */
    tbp->keymap[CLEKEY_END] = CLEFUN_GOTOEOL;	/* goto end of line */
    tbp->keymap[CLEKEY_F12] = CLEFUN_BELL;	/* for test purposes */
    return;
}

/***************************************************************************
 * The following init's setup the strings required to make a terminal do the 
 * given functions.
 */
    static int setup_ansi_defaults(tbp)
    struct tty_buf *tbp;
/* 
 * At entry:
 *	tbp - ptr to tty_buf into which to stick the defaults 
 * At exit:
 *	ansi[] array filled with defaults 
 */
{
    tbp->ansi[ANSI_UP] = ANSI_UP_STR;		/* up-arrow */
    tbp->ansi[ANSI_CLREOL] = ANSI_CLREOL_STR;	/* clear to eol */
    tbp->ansi[ANSI_CLRLINE] = ANSI_CLRLINE_STR;	/* clear whole line */
    tbp->ansi[ANSI_SETINV] = ANSI_SETINV_STR;	/* set inverse video */
    tbp->ansi[ANSI_SETNORM] = ANSI_SETNORM_STR;	/* set normal video */
    tbp->ansi[ANSI_SAVE] = ANSI_SAVE_STR;	/* save cursor pos and attr's */
    tbp->ansi[ANSI_RESTORE] = ANSI_RESTORE_STR;	/* restore cursor pos and attr's */
    tbp->ansi[ANSI_MSGEOF] = ANSI_MSGEOF_STR;	/* EOF message */
    tbp->ansi[ANSI_MSGINTR] = ANSI_MSGINTR_STR; /* INTR message */
    tbp->ansi[ANSI_MSGQUIT] = ANSI_MSGQUIT_STR; /* QUIT message */
    tbp->ansi[ANSI_SETUP] = ANSI_SETUP_STR;	/* set terminal to app mode */
    tbp->ansi[ANSI_80COL] = ANSI_80COL_STR;	/* set to 80 cols */
    tbp->ansi[ANSI_132COL] = ANSI_132COL_STR;	/* set to 132 cols */
#if _SPTALLOC
    if (tbp->tmpbuf != 0) {			/* if there's a temp buff */
	sptfree(tbp->tmpbuf,tbp->tmpsize,1);	/* give back the memory */
	tbp->tmpbuf = 0;
	tbp->tmpsize = 0;
    }
#else
    tbp->tmpsize = 0;
#endif
    return;
}
@//E*O*F cledefault.c//
chmod u=rw,g=r,o=r cledefault.c
 
echo x - master.awk
sed 's/^@//' > "master.awk" <<'@//E*O*F master.awk//'
{
	if ($0 == "$$$" && i++ == 1) {
		printf("cled	cleopen cleclose cleread clewrite cleioctl cleinput cleoutput nulldev\n")
	}
	print;
}	
	    
		   
@//E*O*F master.awk//
chmod u=rw,g=r,o=r master.awk
 
echo x - mkcledc
sed 's/^@//' > "mkcledc" <<'@//E*O*F mkcledc//'
if [ -f cled.c ] 
then
	exit 0
else 
	if [ -f cleda* ]
	then
		echo "Gluing cleda* together to create cled.c..."
		cat cleda* > cled.c
		rm cleda*
	else
		echo "cleda* missing. Need them to build cled.c"
		cleanup
		exit 1
	fi
fi

@//E*O*F mkcledc//
chmod u=rw,g=r,o=r mkcledc
 
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
    198   1725   9836 README
     51    372   2180 README.UNIX
    163   1454   8426 cled.doc
    140    919   5553 cledsetup.doc
    230   1607   9649 cled_ioctl.h
    153    914   6045 cled_structs.h
     96    568   4584 cledefault.c
      8     22    149 master.awk
     16     42    231 mkcledc
   1055   7623  46653 total
!!!
wc  README README.UNIX cled.doc cledsetup.doc cled_ioctl.h cled_structs.h cledefault.c master.awk mkcledc | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0

-- 
Dave Shepperd.	    shepperd at dms.UUCP or motcsd!dms!shepperd
Atari Games Corporation, 675 Sycamore Drive, Milpitas CA 95035.
Nobody knows what I'm saying. I don't even know what I'm saying.



More information about the Comp.unix.i386 mailing list