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.xenix
mailing list