CLED 2.5 SysV/386 part 01/03
Piercarlo Grandi
pcg at cs.aber.ac.uk
Wed Aug 29 02:28:57 AEST 1990
This is the implementation of CLED, a line dicipline for System V/386
3.2 that implements command history in the kernel. It originally came
from Atari Corp. for Xenix; I have worked on it a lot to simplify and
clean it, and to make it more conforming to the Installable Driver
scheme of System V/386. I use it all the time, even if it is not the
msot elegant thing in the world :-). Well, it is surely more convenient
and efficient than command line editing libraries attached to shells and
other programs.
It should be easily modified for Xenix and SCO Unix; I run it under ENIX
rev. A, which is a fairly standard version of AT&T Systm V/386.
Usual disclaimer: this has nothing to do with the University
College of Wales, which has not aided or funded in any way the
work on this software. It is entirely part of my own research
activity, supported and funded entirely by myself. I give many
thanks to the College however for providing me with news access,
which makes this posting possible.
Many thanks again to the people at Atari Corp. that wrote and posted
the original version.
-------------------------cut here---------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 3)."
# Contents: Makefile Master Node README System cled.h cledio.h
# config.h kernel_space.c patchlevel.h scled.c space.c
# Wrapped by sw at aware on Tue Aug 28 13:36:09 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1356 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# $Id: Makefile,v 2.5 90/08/28 13:35:06 sw Exp $
X
XDEV =cled
XSYS =/usr/include/sys
XLSYS =/usr/local/include/sys
XPACK =/etc/conf/pack.d
XKFLAGS =-DINKERNEL
XCFLAGS =-O -Zp4 -I$(LSYS)
XLIBS =$$LDPATH -lmisc -lmalloc -lc_s
X
XCC =cc
X
Xall: s$(DEV) Driver.o $(DEV) #$(DEV)dump
X
XDriver.o: $(DEV).o; ln $? $@
XSpace.c: space.c; ln $? $@
X
X$(DEV).o: $(DEV).c $(LSYS)/$(DEV).h $(LSYS)/$(DEV)io.h
X $(CC) $(CFLAGS) $(KFLAGS) -c $(DEV).c
X
Xs$(DEV): s$(DEV).c $(LSYS)/$(DEV)io.h
X $(CC) $(CFLAGS) -o s$(DEV) s$(DEV).c $(LIBS)
X
X$(DEV): $(DEV).c space.o $(LSYS)/$(DEV).h $(LSYS)/$(DEV)io.h config.h
X $(CC) $(CFLAGS) -o $(DEV) $(DEV).c space.o
X rm -f $(DEV).o space.o
X
Xspace.o: space.o $(LSYS)/$(DEV).h $(LSYS)/$(DEV)io.h config.h
X $(CC) $(CFLAGS) $(KFLAGS) -c space.c
X
X#$(DEV)dump: $(DEV)dump.c $(LSYS)/$(DEV)io.h $(LSYS)/$(DEV).h
X# $(CC) $(CFLAGS) $(KFLAGS) -o $(DEV)dump $(DEV)dump.c $(LIBS)
X
X$(SYS)/$(DEV).h: $(LSYS)/$(DEV).h; ln $? $@
X$(SYS)/$(DEV)io.h: $(LSYS)/$(DEV)io.h; ln $? $@
X$(LSYS)/$(DEV).h: $(DEV).h; cp $? $@
X$(LSYS)/$(DEV)io.h: $(DEV)io.h; cp $? $@
X
Xinstall: $(PACK)/kernel/space.c
Xinstall: $(SYS)/$(DEV).h $(SYS)/$(DEV)io.h
Xinstall: Master System Driver.o Space.c Node Name
X $(CONF)idinstall -kea -msopn $(DEV)
X $(CONF)idmknod -s; chmod a=rw /dev/$(DEV)
X
X$(PACK)/kernel/space.c: kernel_space.c
X @echo You must still change $@ according to $?
END_OF_FILE
if test 1356 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'Master' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Master'\"
else
echo shar: Extracting \"'Master'\" \(29 characters\)
sed "s/^X//" >'Master' <<'END_OF_FILE'
Xcled Ii ico cled 0 0 1 32 -1
END_OF_FILE
if test 29 -ne `wc -c <'Master'`; then
echo shar: \"'Master'\" unpacked with wrong size!
fi
chmod +x 'Master'
# end of 'Master'
fi
if test -f 'Node' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Node'\"
else
echo shar: Extracting \"'Node'\" \(14 characters\)
sed "s/^X//" >'Node' <<'END_OF_FILE'
Xcled cled c 0
END_OF_FILE
if test 14 -ne `wc -c <'Node'`; then
echo shar: \"'Node'\" unpacked with wrong size!
fi
chmod +x 'Node'
# end of 'Node'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(4246 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X$Id: README,v 2.5 90/08/26 11:31:46 sw Exp $
X
XThis is a line discipline that implements input history management. It
Xwas written originally by Lyle Rains of Atari for RT-11, ported by Dave
XSheppard of Atari to Xenix/386, and ported by Piercarlo Grandi to System
XV/386 3.2, as well as _much_ cleaned up and modified.
X
XThis README file has been written entirely by Piercarlo Grandi, and so
Xare all the comments herein.
X
XFirst of all, while I think this is a very useful driver, and though I
Xhave struggled a lot to make it more like I would have done it, I have
Xnot substantially changed it, even if there are a series of things that
XI would have done very differently.
X
XThe current advantages of CLED are:
X
X * It is fully kernel resident, and will keep in the history buffer
X all input, by whatever program. There is no need to add an
X inefficient raw or cbreak mode library to each program or to hack
X with ptys to have history processing.
X
X * It is quite fast, and surely has less overhead than other input
X history mechanisms.
X
X * It can be easily ported to different types of UNIX, and will work
X virtually unchanged on any System V (or V7) derivative.
X
X * It will get out of the way when not needed, e.g. for raw or
X cbreak input.
X
X * It is free.
X
XThe disadvantages are:
X
X * The history mechanism is pretty simple; there are no pattern
X searches, for example. This is probably a feature.
X
X * It occupies wired down kernel space. This is probably a feature,
X because any other interactive history mechanism would probably cost
X vastly more in both space and time overheads.
X
X * It is not easily extensible, as it is linked with the kernel.
X Again, this is probably a feature.
X
X * There is no command or file name completion. This can be
X efficiently implemented by any interested program on top of CLED by
X using the VEOL2 character as trigger.
X
XThere are some things that I would have done differently:
X
X * Design and coding are often quite opaque, and source and object
X sizes too large (4000 lines!). Cleverer design and coding would
X probably shrink both substantially.
X
X * CLED is piggybacked onto line discipline 0; it should be
X standalone, to allow for getting rid of the standard line discipline
X completely.
X
X * Buffers should have been stolen from the buffer cache, instead of
X statically allocated (sptalloc() is no help because of its
X impossibly large granularity).
X
X * Currently when the user logs out the history is not cleared,
X because technically the tty device is not closed. This is a
X security hazard, even if not as bad as it looks, because CLED
X disables itself during not echoed or raw input, so that passwords
X are not recorded (passwords passed as arguments to a command are a
X security hazard anyhow).
X
X * Saving, resetting, and restoring the current history buffer should
X therefore become better supported.
X
X * The ioctl(2) codes should allow setting key bindings and terminal
X capabilities independently. In general the ioctl(2) interface is
X quite clumsy.
X
X * The scled(1) command should be completely rewritten.
X
XThere are also a few known problems, but they are usually not mistakes
Xbut rather compromises (e.g. when inserting tabs in the middle of the
Xline, the check on line length is circumvented). Surely there are also
Xlots of real bugs.
X
XTo install CLED, have a look at the "Makefile" (should be ok on most any
XUNIX), and at files "cled.h" and "space.c". It is suggested that you do
Xnot change the configuration options at the top of "cled.h"; not only I
Xhave not tested other configurations, but enabling the most
Xsophisticated options of CLED substantially enlarges it. In particular,
Xunless you know better, do not enable SPTALLOC.
X
XAs to the buffer sizes, I think the ones given are OK for most anybody;
Xnote that CLED will not allow you to type a line longer than the current
Xscreen size, so the MAXLINE parameter is really the maximum number of
Xcolumns on a terminal, and 132 is therefore sufficient. As to
XMAXPROMPT, I hope you do not use garish long prompts... In any case
Xthis is the number of characters remembered in the prompt, not its
Xmaximum size.
END_OF_FILE
if test 4246 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
chmod +x 'README'
# end of 'README'
fi
if test -f 'System' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'System'\"
else
echo shar: Extracting \"'System'\" \(23 characters\)
sed "s/^X//" >'System' <<'END_OF_FILE'
Xcled Y 6 0 0 0 0 0 0 0
END_OF_FILE
if test 23 -ne `wc -c <'System'`; then
echo shar: \"'System'\" unpacked with wrong size!
fi
chmod +x 'System'
# end of 'System'
fi
if test -f 'cled.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'cled.h'\"
else
echo shar: Extracting \"'cled.h'\" \(6029 characters\)
sed "s/^X//" >'cled.h' <<'END_OF_FILE'
X/*
X $Id: cled.h,v 2.5 90/08/26 11:33:56 sw Exp $
X*/
X/*
X This should be set, if compiling as line discipline, in the command line
X*/
X
X#ifndef M_KERNEL
X# define M_KERNEL 0
X#endif
X
X/*
X These are booleans and describe the environment in which CLED
X is compiled and run. Even if you are on a 386 with a Unix that
X has sptalloc()/sptfree() you will normally not want to use it,
X because it allocates memory in page (4096 bytes) chunks.
X*/
X
X#define M_I386 1 /* Running on a 386 ? */
X#define M_UNIX 1 /* System V/SCO Unix ? (or Xenix?) */
X#define M_ATT 1 /* AT&T flavour of System V ? */
X#define M_SPTALLOC 0 /* Kernel has, and we should use, it */
X
X/*
X These are boolean options. DEBUG should normally be 0. The code
X compiled in if CLEDIO is true is large; if you don't need to change
X the default terminal capabilities and key bindings, set it to 0.
X BREAKTHRU compiles in a nother large chunk of code that will
X automatically reprint the current line if a write to the tty garbles
X it. You should normally set this to 0 and just explicitly request a
X redraw in the rare event this happens. MULTILB will dynamically
X allocate a separate history buffer per process, not just one per
X tty. This is usually not what you want, and makes code and data
X space grow.
X*/
X
X#define DEBUG 0 /* Compile in debugging helps */
X
X#define CLEDIO 1 /* Include ioctls to change defaults ? */
X#define BREAKTHRU 0 /* Auto reprint on broadcasts ? */
X#define MULTILB 0 /* Separate history per process ? */
X#define VERBOSE 0 /* Print a msg each time CLED opens */
X
X#define COLUMNS 80 /* Default number of columns */
X
X/*
X These set sizes of various buffers. Suitable values depend on the
X amount of memory you want to devote to CLED, and its availability.
X For a 386 you may want these to be 1024,32,134,64, and for a 286
X they may be 256,16,82,64.
X*/
X
X#define MAXPROMPT 16 /* Size of prompt buffer */
X#define MAXLINE 132 /* Size of command line buffer */
X#define MAXHISTORY 1024 /* Size of history buffer */
X#if !M_SPTALLOC
X# define TCAP_SIZE 64 /* max length of all terminal escapes */
X#endif
X
X/* End of user adjustable parameters */
X
X/*
X Under which termio conditions CLED will operate
X*/
X
X#define CLEDOFF(flags) (((flags) & CLEDFLAGS) != CLEDFLAGS)
X
X#if 0
X#if M_KERNEL
X# undef MULTILB
X# undef M_SPTALLOC
X# define M_SPTALLOC 0
X# define MULTILB 0
X# if !defined(TCAP_SIZE)
X# define TCAP_SIZE 64
X# endif
X#endif
X#endif
X
X#define LD_DONE 0x0001 /* flag indicating read complete */
X#define LD_QUIT 0x0002 /* completed under QUIT char */
X#define LD_INTR 0x0004 /* completed under INTR char */
X#define LD_EOF 0x0008 /* completed under EOF */
X#define LD_DIRTY 0x0010 /* command buffer has been changed */
X#define LD_INSERT 0x0020 /* insert mode */
X
X#define TB_NOLINE 0x0001 /* not using this discipline */
X#define TB_OPEN 0x0002 /* tty buff is open */
X#define TB_READING 0x0004 /* read currently in progress */
X#define TB_WRITING 0x0008 /* write currently in progress */
X#define TB_INSERT 0x0010 /* insert mode */
X#define TB_OVERUN 0x0020 /* input buffer overrun */
X#define TB_OPENING 0x0040 /* tty buf is opening */
X#define TB_FLUSHIT 0x0080 /* flush the input que */
X
X/*
X if last flag is greater than 0x8000, change flags from short to long
X*/
X
X#ifdef M_I386
X# pragma pack(1)
X#endif
X
Xstruct led_buf
X{
X#if MULTILB
X struct led_buf *next;
X struct led_buf *last;
X struct proc *proc;
X#endif
X
X struct tty_buf *tbp; /* Tty buf that owns us */
X
X unchar prompt[MAXPROMPT+1]; /* +1: Final '\0' */
X unchar promptlen; /* Current length of prompt */
X
X unchar line[MAXLINE+2]; /* +2: Left&right mark */
X unchar *lineend; /* End of line in buf */
X unchar *lcurs; /* Start of gap in buf */
X unchar *rcurs; /* End of gap in buf */
X unchar *owed; /* Part of line left over */
X
X int current; /* Cursor position */
X int lastchar; /* Last char in line buf */
X
X unchar history[MAXHISTORY+1]; /* +1: Final '\0' */
X unchar *historyend;/* End of history buffer */
X int lastline; /* Last line in history buf */
X int matchlen; /* Length of match string */
X
X unsigned flags;
X unsigned state;
X
X unchar c; /* Character being input */
X
X#if MULTILB
X int pid;
X int ppid;
X#endif
X};
X
X#ifdef M_I386
X# pragma pack()
X#endif
X
Xstruct tty_buf
X{
X struct tty_buf *next;
X struct tty_buf *last;
X
X struct led_buf *lbp; /* Pointer to line buffer */
X struct tty *ttyp; /* The tty we are serving */
X
X int cols; /* Terminal line width */
X
X unsigned iflag;
X unsigned oflag;
X unsigned lflag;
X unsigned cflag;
X char cc[NCC + 2];
X
X unsigned flags;
X char dorefresh; /* Refresh current line soon */
X char readsleep; /* Sleeping while reading */
X
X struct clist broadcast;
X
X /*
X Keyboard map, and terminal capability index and table
X for this tty.
X */
X unchar keymap[CLEKEY_MAX];
X
X char *tcap[TCAP_COUNT];
X
X int tclen;
X#if M_SPTALLOC
X unchar *tcstrings;
X#else
X unchar tcstrings[TCAP_SIZE];
X#endif
X};
X
X#if M_SPTALLOC && M_KERNEL
X# if M_UNIX
X extern caddr_t *sptalloc(/* int pages,int mode,int base,int flag */);
X extern void sptfree(/* char *va,int npages,int freeflag */);
X
X# define Sptalloc(bytes) sptalloc(btopt(bytes),PG_P,0,0)
X# define Sptfree(addr,bytes) sptfree(addr,btopt(bytes),1)
X# else
X# define Sptalloc(bytes) sptalloc(bytes)
X# define Sptfree(addr,bytes) sptfree(addr,bytes,1)
X# endif
X#else
X# if !M_KERNEL
X# define Sptalloc(size) malloc(size)
X# define Sptfree(addr,size) free(addr)
X# endif
X#endif
END_OF_FILE
if test 6029 -ne `wc -c <'cled.h'`; then
echo shar: \"'cled.h'\" unpacked with wrong size!
fi
chmod +x 'cled.h'
# end of 'cled.h'
fi
if test -f 'cledio.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'cledio.h'\"
else
echo shar: Extracting \"'cledio.h'\" \(6898 characters\)
sed "s/^X//" >'cledio.h' <<'END_OF_FILE'
X/*
X $Id: cledio.h,v 2.5 90/08/26 11:35:00 sw Exp $
X*/
X
X/*
X CLED will be active only if this options are set
X*/
X
X#define CLEDFLAGS (ICANON|ECHO|ECHOE|ECHOK)
X
X/*
X Terminal capabilities remembered by CLED
X*/
X
X#define TCAP_CLREOL_STR "\033[K" /* clear to eol */
X#define TCAP_SETINV_STR "\033[7m" /* set inverse video */
X#define TCAP_SETNORM_STR "\033[m" /* set normal video */
X#define TCAP_SAVE_STR "\0337" /* save cursor pos and attr */
X#define TCAP_RESTORE_STR "\0338" /* restore pos and attr */
X#define TCAP_FLASH_STR "\007" /* ring bell or similar */
X
X#define TCAP_CLREOL 0
X#define TCAP_SETINV 1
X#define TCAP_SETNORM 2
X#define TCAP_SAVE 3
X#define TCAP_RESTORE 4
X#define TCAP_FLASH 5
X#define TCAP_COUNT 6 /* last one indicates total */
X
X/*
X ioctl codes available
X*/
X
X#define LDIOC ('D'<<8)
X
X/*
X Ioctls on the line discipline itself
X*/
X
X#define LDGETCOLS (LDIOC|14) /* Get terminal line length */
X#define LDSETCOLS (LDIOC|15) /* Set terminal line length */
X
X#define LDGETBF (LDIOC|16) /* get bindings & capabilities */
X#define LDSETBF (LDIOC|17) /* set bindings & capabilities */
X
X#define LDGETHB (LDIOC|18) /* get history buffer */
X#define LDSETHB (LDIOC|19) /* set history buffer */
X
X/*
X Ioctls on the CLED driver in general
X*/
X
X#define LDGETS (LDIOC|20) /* get cled stats */
X
X#define LDGETB (LDIOC|21) /* dump its guts (debug mode only) */
X#define LDGETTTY (LDIOC|22) /* dump a tty struct (debug mode only) */
X#define LDGETC (LDIOC|23) /* dump contents of a clist (debug only) */
X
X/*
X Error codes returned from ioctl functions
X*/
X
X#define ERR_NOTTYBUF 12 /* ENOMEM no more ttybufs available */
X#define ERR_NOLEDBUF 11 /* EAGAIN no more ledbufs available */
X#define ERR_NOLBASS 19 /* ENODEV no led buf assigned to process */
X#define ERR_BADPARAM 22 /* EINVAL bad paramater value */
X#define ERR_BADIOCTL 33 /* EDOM bad ioctl function */
X
X/*
X Pass the address of this struct to LDGETS
X*/
X
Xstruct cle_stats
X{
X int ledbufs; /* max number of led_buffers */
X int ttybufs; /* max number of tty_buffers */
X int promptsize; /* size of prompt buffer */
X int linesize; /* size of command buffer */
X int histsize; /* size of history buffer */
X int multi_lb; /* t/f flag indicating multi-lb mode */
X int spt; /* t/f flag indicating using sptalloc */
X int tcapsize; /* max length of all ascii strings */
X int ledbufs_used; /* number of led_buf's in use */
X int ttybufs_used; /* number of tty_buf's in use */
X int line; /* cled's line discipline number */
X char vers[4]; /* version # */
X};
X
X/*
X Pass the address of this struct to LDGETB/LDSETB
X*/
X
Xstruct cle_buf
X{
X int lbsize;
X int tbsize;
X struct led_buf *lbbase;
X struct led_buf *lbfree;
X struct tty_buf *tbbase;
X struct tty_buf *tbused;
X struct tty_buf *tbfree;
X struct proc *procbase;
X};
X
X/*
X Pass this struct for LDGETF/LDSETF.
X
X The following structure is passed to the ioctl routine to
X /dev/cled to assign the key bindings and the TCAP sequences
X (and other strings) desired for various functions.
X
X If the ioctl completes with an error, then the len fields of
X the struct will have been changed to an index into the
X respective buffer at which the error occured (the driver sets
X the value).
X
X The key buffer immediately follows the set_key struct and the
X TCAP buffer immediately follows the key buffer.
X
X The key buffer contains pairs of chars; the first is the key
X number and the second is the function number. The kdbuf_len
X entry in the set_key struct contains the total number of these
X pairs of chars. Any of the control keys and/or keypad keys can
X be set to any function at any time. New definitions replace
X previous definitions. Keys not explicitly defined in the
X buffer are left defined to whatever they were.
X
X The TCAP buffer consists of a stream of null terminated strings
X preceeded by the number of the sequence to which the string
X belongs. If any TCAP sequence is defined, then ALL the
X sequences are first reset to their defaults and then replaced
X with the new definitions. That is, you can change one or all,
X but unlike the key definitions, you cannot change just one
X without affecting all the others.
X*/
X
Xstruct set_key
X{
X int modes; /* default mode bits */
X int kdbuf_len; /* key buffer length (in items) */
X int tcapbuf_len; /* length of escapes (in chars) */
X};
X
X/*
X We implement a very contrived set of key bindings; we have
X the 32 control characters, then 96 meta characters, then
X DEL. We don't provide for bindint to x or M-C-x, only
X either C-x or M-x.
X
X To bind to M-x, use CLEKEY_ESC(x), to bind to C-x, use CLEKEY_CTL(x).
X*/
X
X#define CLEKEY_CHAR(c) ((c) >= ' ' && (c) <= '~')
X
X#define CLEKEY_CMD(c) ((c)&0x7F)
X#define CLEKEY_ESC(c) ((c)&0x7F)
X#define CLEKEY_CTL(c) ((c)&0x1F)
X#define CLEKEY_DEL 0x7F
X
X#define CLEKEY_MAX 0x80
X
X/*
X default modes
X*/
X
X#define CLEMODE_INSERT 0x01 /* insert mode */
X#define CLEMODE_OVER 0x02 /* overstrike mode */
X
X/*
X Editor functions: (don't change the order of these)
X*/
X
X#define CLEFUN_CHAR 0x00 /* insert character into buffer */
X#define CLEFUN_INSERT 0x01 /* toggle insert/overstrike mode */
X#define CLEFUN_GOTOBOL 0x02 /* goto beginning of line */
X#define CLEFUN_GOTOEOL 0x03 /* goto end of line */
X#define CLEFUN_DELWLFT 0x04 /* delete word to left of cursor */
X#define CLEFUN_DELWRIT 0x05 /* delete word to right of cursor */
X#define CLEFUN_DELBOL 0x06 /* delete from cursor to beginning of line */
X#define CLEFUN_DELEOL 0x07 /* delete from cursor to end of line */
X#define CLEFUN_CURSL 0x08 /* move cursor left 1 position */
X#define CLEFUN_CURSR 0x09 /* move cursor right 1 position */
X#define CLEFUN_DELCLFT 0x0A /* delete char left of cursor */
X#define CLEFUN_DELCRIT 0x0B /* delete char under cursor */
X#define CLEFUN_REFRESH 0x0C /* reprint the current line */
X#define CLEFUN_PREVIOUS 0x0D /* recall previous command */
X#define CLEFUN_NEXT 0x0E /* recall next command */
X#define CLEFUN_FIND 0x0F /* find matching string */
X#define CLEFUN_NEWLINE 0x10 /* end of line */
X#define CLEFUN_ESCAPE 0x11 /* "escape" the next character */
X#define CLEFUN_NOP 0x12 /* nop */
X#define CLEFUN_BELL 0x13 /* ring bell */
X#define CLEFUN_SKIPWL 0x14 /* skip word left */
X#define CLEFUN_SKIPWR 0x15 /* skip word right */
X#define CLEFUN_PURGE 0x16 /* purge all typeahead */
X#define CLEFUN_META 0x17 /* access chars with 8th bit on */
X#define CLEFUN_ANSI 0x18 /* parse ansi cursor sequence */
X#define CLEFUN_MAX 0x19 /* number of functions */
END_OF_FILE
if test 6898 -ne `wc -c <'cledio.h'`; then
echo shar: \"'cledio.h'\" unpacked with wrong size!
fi
chmod +x 'cledio.h'
# end of 'cledio.h'
fi
if test -f 'config.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'config.h'\"
else
echo shar: Extracting \"'config.h'\" \(301 characters\)
sed "s/^X//" >'config.h' <<'END_OF_FILE'
X/* fake config.h used to test compiling space.c */
X
X#define CLED 1
X#define CLED_CNTLS 1
X#define CLED_UNITS 6
X#define CLED_CHAN -1
X#define CLED_TYPE 0
X
X#define CLED_0 6
X#define CLED_0_VECT 0
X#define CLED_0_SIOA 0
X#define CLED_0_EIOA 0
X#define CLED_0_SCMA 0
X#define CLED_0_ECMA 0
X
X#define NCLEPROCS 1
END_OF_FILE
if test 301 -ne `wc -c <'config.h'`; then
echo shar: \"'config.h'\" unpacked with wrong size!
fi
chmod +x 'config.h'
# end of 'config.h'
fi
if test -f 'kernel_space.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'kernel_space.c'\"
else
echo shar: Extracting \"'kernel_space.c'\" \(324 characters\)
sed "s/^X//" >'kernel_space.c' <<'END_OF_FILE'
X/*
X Append the following lines at the appropriate place in
X /etc/conf/pack.d/kernel/space.c
X*/
X
X#ifdef CLED
X/* cled ------------- */
X cleopen,
X cleclose,
X cleread,
X clewrite,
X cleioctl,
X cleinput,
X cleoutput,
X nulldev,
X#endif
X};
X
X#ifdef CLED
Xint linecnt = 4;
X#else
Xint linecnt = 3;
X#endif
END_OF_FILE
if test 324 -ne `wc -c <'kernel_space.c'`; then
echo shar: \"'kernel_space.c'\" unpacked with wrong size!
fi
chmod +x 'kernel_space.c'
# end of 'kernel_space.c'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(41 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define VERSION "2"
X#define PATCHLEVEL 5
END_OF_FILE
if test 41 -ne `wc -c <'patchlevel.h'`; then
echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
chmod +x 'patchlevel.h'
# end of 'patchlevel.h'
fi
if test -f 'scled.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'scled.c'\"
else
echo shar: Extracting \"'scled.c'\" \(18349 characters\)
sed "s/^X//" >'scled.c' <<'END_OF_FILE'
X/*
X $Id: scled.c,v 2.5 90/08/26 11:35:26 sw Exp $
X*/
X
X#include <sys/types.h>
X#include <sys/tty.h>
X
X#include <sys/termio.h>
X
X#include <stdio.h>
X#include <ctype.h>
X#include <fcntl.h>
X#include <sys/ioctl.h>
X#include <errno.h>
X
X#include <sys/cledio.h>
X#include <sys/cled.h>
X
Xint cols = -1;
Xunchar *buf;
Xunchar inpbuf[256];
Xstruct termio tio;
Xextern unchar *malloc(),*getenv();
X
XFILE *ifp;
Xint cledp;
X
Xunchar *cledfn = (unchar *) "/dev/cled";
Xunchar *empty = (unchar *) "";
X
Xstruct cle_stats stats;
X
Xstruct items
X{
X int numb;
X char *str;
X};
X
Xstruct items tcap_seq[] =
X{
X {TCAP_CLREOL,"clreol"},
X {TCAP_SETINV,"setinv"},
X {TCAP_SETNORM,"setnorm"},
X {TCAP_SAVE,"save"},
X {TCAP_RESTORE,"restore"},
X {TCAP_FLASH,"flash"},
X 0
X};
X
Xstruct items func_names[] =
X{
X {CLEFUN_INSERT,"insert"},
X {CLEFUN_INSERT,"overstrike"},
X {CLEFUN_GOTOBOL,"goto_bol"},
X {CLEFUN_GOTOEOL,"goto_eol"},
X {CLEFUN_DELWLFT,"del_word_left"},
X {CLEFUN_DELWRIT,"del_word_right"},
X {CLEFUN_DELBOL,"del_to_bol"},
X {CLEFUN_DELEOL,"del_to_eol"},
X {CLEFUN_CURSL,"cursor_left"},
X {CLEFUN_CURSR,"cursor_right"},
X {CLEFUN_DELCLFT,"del_char_left"},
X {CLEFUN_DELCRIT,"del_char_right"},
X {CLEFUN_REFRESH,"refresh"},
X {CLEFUN_PREVIOUS,"previous"},
X {CLEFUN_NEXT,"next"},
X {CLEFUN_FIND,"find"},
X {CLEFUN_NEWLINE,"newline"},
X {CLEFUN_ESCAPE,"superquote"},
X {CLEFUN_NOP,"nop"},
X {CLEFUN_BELL,"bell"},
X {CLEFUN_SKIPWR,"skip_word_right"},
X {CLEFUN_SKIPWL,"skip_word_left"},
X {CLEFUN_PURGE,"purge"},
X {CLEFUN_META,"meta"},
X {CLEFUN_ANSI,"ansi"},
X {0,0}
X};
X
Xunchar *rev_funcnames[CLEFUN_MAX];
Xunchar *rev_tcapnames[TCAP_COUNT];
Xunchar *set_tcapnames[TCAP_COUNT];
Xchar *tcap_defs[TCAP_COUNT];
X
Xstruct cle_stats stats;
Xint line = 0,errors = 0;
Xunchar delim[] = " \t\n";
Xunchar *pathptrs[4];
X
X#define ACC_EXISTS 0
X#define ACC_EXECUTE 1
X#define ACC_WRITE 2
X#define ACC_READ 4
X
X
Xstatic unchar *rev_keyname(key)
X int key;
X{
X static unchar name[8];
X
X if (CLEKEY_CHAR(key))
X (void) sprintf(name,"M-%c",key);
X else (void) sprintf(name,"^%c",(key == 0x7F) ? '?' : key+'@');
X
X return name;
X}
X
X/*
X get_pathname is a function that takes as input an array of unchar *'s
X which are presumed to be path names and a unchar * which is assumed to be
X a filename. It builds a real filename by gluing each of the path names
X successively to the filename and doing an access test on the composite
X name. It returns a pointer to the composite string if the file is
X accessable otherwise it returns null.
X
X At entry: paths - ptr to (unchar *) 0 terminated array of unchar pointers each
X pointing to null terminated pathname string. filename - ptr to filename
X string amode - access mode which to use to test according to the
X following: 00 - check for file existance 01 - check for execute (search)
X 02 - check for write 04 - check for read At exit: returns ptr to composite
X string from malloc'd memory if file accessable else returns NULL.
X*/
X
Xunchar *get_pathname(paths,filename,amode)
X unchar **paths,*filename;
X int amode;
X{
X unchar *s;
X int fnlen;
X
X fnlen = strlen(filename) + 1;
X if (filename[0] == '/' ||
X (filename[0] == '.' && filename[1] == '/' ||
X (filename[1] == '.' && filename[2] == '/')))
X paths = (unchar **) 0;
X
X while (paths != (unchar **) 0 && *paths != (unchar *) 0)
X {
X int plen;
X
X plen = strlen(*paths);
X s = malloc(plen + fnlen);
X strcpy(s,*paths);
X strcat(s,filename);
X if (access(s,amode) == 0)
X return s;
X free(s);
X ++paths;
X }
X
X /* check the filename without a path */
X if (access(filename,amode) == 0)
X {
X s = malloc(fnlen);
X strcpy(s,filename);
X return s;
X }
X return (unchar *) 0;
X}
X
Xint show_error(what,token)
X unchar *what,*token;
X{
X if (token == 0)
X fprintf(stderr,"Missing %s on line %d\n",what,line);
X else
X fprintf(stderr,"Unknown %s {%s} on line %d\n",what,token,line);
X ++errors;
X}
X
Xunchar *outfile = 0;
Xunchar *inpfile = 0;
X
X#ifdef NOISY
Xdump_text(ptr,len)
X unchar *ptr;
X int len;
X{
X int i,j;
X unchar *l;
X
X while (len > 0)
X {
X l = ptr;
X j = (len > 32) ? 32 : len;
X for (i = 0; i < j; ++i)
X fprintf(stderr,"%02X ",*(l + i));
X fputs("\n",stderr);
X for (i = 0; i < j; ++i)
X fprintf(stderr," %c ",(*(l + i) > ' ') ? *(l + i) : '.');
X fputs("\n",stderr);
X ptr += j;
X len -= j;
X }
X}
X
X#endif
X
Xvoid ioctl_error(old)
X struct set_key *old;
X{
X int key,kie,func;
X unchar *kp;
X struct set_key *skp;
X
X skp = (struct set_key *) buf;
X kp = (unchar *) (skp + 1);
X kp += skp->kdbuf_len * 2;
X
X if (old->kdbuf_len != skp->kdbuf_len)
X {
X kie = *kp++;
X func = *kp++;
X fprintf(stderr,"Error setting Key 0x%02X (%s) to func 0x%02X (%s)\n",
X kie,((kie < CLEKEY_MAX) ? rev_keyname(kie) : empty),
X func,((func < CLEFUN_MAX) ? rev_funcnames[func] : empty));
X }
X else if (old->tcapbuf_len != skp->tcapbuf_len)
X {
X int i;
X unchar *t,*s;
X
X i = strlen(kp) + 1;
X if ((t = (unchar *) malloc(i)) == (unchar *) 0)
X {
X fprintf(stderr,"Cannot get %d bytes reporting tcap_set failure",i);
X return;
X }
X
X kie = *kp++;
X for (s = t; i > 0; --i,++kp)
X *s++ = (*kp >= ' ' && *kp < 0177) ? *kp : '.';
X *s = 0;
X fprintf(stderr,"Error setting string 0x%02X (%s) to \"%s\"\n",
X kie,((kie < TCAP_COUNT) ? rev_tcapnames[kie] : empty),t);
X free(t);
X }
X else
X {
X fprintf(stderr,"Error %d setting keys/tcap strings in cled\n",errno);
X fprintf(stderr,"before modes = %08X, kdbuf_len = %d, tcapbuf_len = %d\n",
X old->modes,old->kdbuf_len,old->tcapbuf_len);
X fprintf(stderr,"after modes = %08X, kdbuf_len = %d, tcapbuf_len = %d\n",
X skp->modes,skp->kdbuf_len,skp->tcapbuf_len);
X }
X}
X
Xvoid read_setup()
X{
X int i,anslen = 0;
X unchar *kp,*ap,*abp,*ifn;
X struct set_key *skp;
X
X if (inpfile == (unchar *) 0)
X inpfile = (unchar *) ".cledrc";
X pathptrs[0] = (unchar *) "./";
X
X ap = getenv("CLED");
X if (ap != (unchar *) 0 && (i = strlen(ap)) > 0)
X {
X if (ap[i - 1] != '/')
X {
X kp = malloc(strlen(ap) + 2);
X strcpy(kp,ap);
X strcat(kp,"/");
X ap = kp;
X }
X }
X
X pathptrs[1] = ap;
X ap = getenv("HOME");
X if (ap != (unchar *) 0 && (i = strlen(ap)) > 0)
X {
X if (ap[i - 1] != '/')
X {
X kp = malloc(strlen(ap) + 2);
X strcpy(kp,ap);
X strcat(kp,"/");
X ap = kp;
X }
X }
X
X pathptrs[2] = ap;
X ifn = get_pathname(pathptrs,inpfile,ACC_READ);
X if (ifn == (unchar *) 0)
X {
X if (buf != 0)
X free(buf);
X buf = (unchar *) 0;
X return;
X }
X
X ifp = fopen(ifn,"r");
X if (ifp == 0)
X {
X sprintf(inpbuf,"Unable to open input: %s\n\t",ifn);
X perror(inpbuf);
X exit(1);
X }
X
X tcap_defs[TCAP_CLREOL] = TCAP_CLREOL_STR;
X tcap_defs[TCAP_SETINV] = TCAP_SETINV_STR;
X tcap_defs[TCAP_SETNORM] = TCAP_SETNORM_STR;
X tcap_defs[TCAP_SAVE] = TCAP_SAVE_STR;
X tcap_defs[TCAP_RESTORE] = TCAP_RESTORE_STR;
X tcap_defs[TCAP_FLASH] = TCAP_FLASH_STR;
X
X i = 256 + sizeof (struct set_key) + CLEKEY_MAX * 2;
X buf = (unchar *) malloc(i * 2);
X if (buf == 0)
X {
X fprintf(stderr,"Unable to allocate %d bytes\n",i);
X exit(1);
X }
X
X skp = (struct set_key *) buf;
X skp->kdbuf_len = 0;
X skp->tcapbuf_len = 0;
X skp->modes = 0;
X
X kp = (unchar *) (skp + 1); /* point to key space */
X abp = ap = kp + CLEKEY_MAX * 2;
X while (fgets(inpbuf,sizeof (inpbuf),ifp) != NULL)
X {
X unchar *tok1,*tok2,c;
X extern unchar *strtok();
X
X ++line;
X tok1 = strtok(inpbuf,delim);
X if (tok1 == 0)
X continue;
X
X if (strcmp(tok1,"columns") == 0)
X {
X tok1 = strtok((unchar *) 0,delim);
X if (tok1 == 0)
X {
X show_error("mode",tok1);
X continue;
X }
X
X cols = atoi(tok1);
X if (cols >= 8 || cols <= MAXLINE)
X continue;
X
X cols = -1;
X
X show_error("mode",tok1);
X continue;
X }
X
X if (strcmp(tok1,"mode") == 0)
X {
X tok1 = strtok((unchar *) 0,delim);
X if (tok1 == 0)
X {
X show_error("mode",tok1);
X continue;
X }
X
X if (strcmp(tok1,"insert") == 0)
X {
X skp->modes |= CLEMODE_INSERT;
X continue;
X }
X
X if (strcmp(tok1,"overstrike") == 0)
X {
X skp->modes |= CLEMODE_OVER;
X continue;
X }
X
X show_error("mode",tok1);
X continue;
X }
X
X if (strcmp(tok1,"key") == 0)
X {
X int key,func;
X
X tok1 = strtok((unchar *) 0,delim);
X if (tok1 == 0)
X {
X show_error("keyname",tok1);
X continue;
X }
X
X if (tok1[0] == '^')
X key = (tok1[1] == '?') ? 0x7F : CLEKEY_CTL(tok1[1]);
X else if (tok1[0] == '_')
X key = CLEKEY_ESC(tok1[1]);
X else if (tok1[0] == 'M' && tok1[1] == '-')
X key = CLEKEY_ESC(tok1[2]);
X else
X {
X show_error("keyname",tok1);
X continue;
X }
X
X tok1 = strtok((unchar *) 0,delim);
X if (tok1 == 0)
X {
X show_error("function name",tok1);
X continue;
X }
X
X for (func = 0; func_names[func].numb > 0; ++func)
X if (strcmp(func_names[func].str,tok1) == 0)
X break;
X
X if (func_names[func].numb == 0)
X {
X show_error("function name",tok1);
X continue;
X }
X
X skp->kdbuf_len += 1;
X *kp++ = key;
X *kp++ = func_names[func].numb;
X continue;
X }
X
X if (strcmp(tok1,"string") == 0)
X {
X int ans;
X unchar *s;
X
X tok1 = strtok((unchar *) 0,delim);
X if (tok1 == 0)
X {
X show_error("string name",tok1);
X continue;
X }
X
X for (ans = 0; tcap_seq[ans].str != 0; ++ans)
X if (strcmp(tcap_seq[ans].str,tok1) == 0)
X break;
X
X if (tcap_seq[ans].str == 0)
X {
X show_error("string name",tok1);
X continue;
X }
X
X tok1 = strtok((unchar *) 0,"\"\r\n");
X if (set_tcapnames[ans] != (unchar *) 0)
X {
X anslen -= strlen(set_tcapnames[ans]) - 1;
X if (anslen < 0)
X anslen = 0;
X free(set_tcapnames[ans]);
X }
X
X if (tok1 != (unchar *) 0)
X {
X s = (unchar *) set_tcapnames[ans] = malloc(strlen(tok1) + 1);
X if (s == (unchar *) 0)
X {
X fprintf(stderr,"Unable to allocate %d bytes of mem\n",
X strlen(tok1) + 1);
X exit(1);
X }
X
X while (*tok1)
X {
X unchar c,*tp;
X
X c = *s++ = *tok1++;
X if (c == '\\')
X {
X int val;
X
X tp = tok1 - 1;
X switch ((c = *tok1++))
X {
X case 't': val = '\t'; break;
X case 'r': val = '\r'; break;
X case 'n': val = '\n'; break;
X case 'f': val = '\f'; break;
X case 'v': val = '\v'; break;
X
X case '0':
X if (*tok1 < '0' || *tok1 > '7')
X {
X val = 0;
X fprintf(stderr,"Warning: null in string on line %d\n",line);
X break;
X }
X
X case '1':
X case '2':
X case '3':
X val = (c - '0') << 6;
X if (*tok1 < '0' || *tok1 > '7')
X {
X show_error("string constant",tp);
X break;
X }
X val |= (*tok1++ - '0') << 3;
X if (*tok1 < '0' || *tok1 > '7')
X {
X show_error("string constant",tp);
X break;
X }
X val |= *tok1++ - '0';
X break;
X
X
X default:
X val = c;
X }
X *(s - 1) = val;
X }
X }
X *s++ = 0;
X anslen += s - set_tcapnames[ans];
X }
X else
X {
X s = set_tcapnames[ans] = malloc(1);
X if (s == (unchar *) 0)
X {
X fprintf(stderr,"Unable to allocate 1 byte");
X exit(1);
X }
X *s = 0;
X anslen += 1;
X }
X continue;
X }
X show_error("keyword",tok1);
X }
X
X if (anslen > stats.tcapsize)
X {
X fprintf(stderr,"Error: Total length of all strings is greater than %d\n",
X stats.tcapsize);
X exit(1);
X }
X if (anslen != 0)
X {
X unchar *bp;
X
X bp = buf + sizeof (struct set_key) + skp->kdbuf_len * 2;
X skp->tcapbuf_len = 0;
X for (i = 0; i < sizeof (set_tcapnames) / sizeof (unchar *); ++i)
X {
X if (set_tcapnames[i] != (unchar *) 0)
X {
X if (strcmp(tcap_defs[i],set_tcapnames[i]) != 0)
X {
X int sln;
X
X *bp++ = i;
X strcpy(bp,set_tcapnames[i]);
X sln = strlen(bp) + 1;
X bp += sln;
X skp->tcapbuf_len += sln + 1;
X }
X free(set_tcapnames[i]);
X set_tcapnames[i] = (unchar *) 0;
X }
X }
X
X#ifdef NOISY
X fprintf(stderr,"Found %d bytes of ascii defines:\n",skp->tcapbuf_len);
X bp = buf + sizeof (struct set_key) + skp->kdbuf_len * 2;
X dump_text(bp,skp->tcapbuf_len);
X#endif
X }
X
X#ifdef NOISY
X fprintf(stderr,"Found modes = %02X, %d key defines, %d bytes of tcap defines and %d errors\n",
X skp->modes,skp->kdbuf_len,skp->tcapbuf_len,errors);
X#endif
X}
X
Xvoid make_output()
X{
X int i;
X unchar *bp,*kp,*ascp;
X FILE *ofp;
X struct set_key *kstr;
X
X ofp = fopen(outfile,"w");
X if (ofp == 0)
X {
X sprintf(inpbuf,"Unable to open %s for write\n\t",outfile);
X perror(inpbuf);
X exit(1);
X }
X
X if (ioctl(fileno(stderr),LDGETCOLS,&cols) < 0)
X {
X perror("error getting # of columns from cled\n\t");
X exit(1);
X }
X
X i = 256 + sizeof (struct set_key) + CLEKEY_MAX * 2;
X bp = malloc(i);
X if (ioctl(fileno(stderr),LDGETBF,bp) < 0)
X {
X perror("error getting key buf from cled\n\t");
X exit(1);
X }
X
X kstr = (struct set_key *) bp;
X kp = bp + sizeof (struct set_key);
X ascp = kp + kstr->kdbuf_len;
X
X#ifdef NOISY
X fprintf(stderr,"kstr=%08X, kp=%08X, ascp=%08X, key_len=%d, asc_len=%d\n",
X kstr,kp,ascp,kstr->kdbuf_len,kstr->tcapbuf_len);
X dump_text(ascp,kstr->tcapbuf_len);
X#endif
X
X fprintf(ofp,"columns %d\n",cols);
X fprintf(ofp,"mode %s\n",(kstr->modes & CLEMODE_INSERT) ? "insert" : "overstrike");
X
X for (i = 0; i < kstr->kdbuf_len; ++i)
X {
X int func,j;
X
X func = *kp++;
X if (func == 0)
X continue;
X if (func >= CLEFUN_MAX)
X {
X fprintf(stderr,"cled returned an unknown function of 0x%02X assigned to key 0x%02X\n",
X func,i);
X continue;
X }
X if (i >= CLEKEY_MAX)
X {
X fprintf(stderr,"cled returned unknown key 0x%02X assigned to function %s\n",
X i,rev_funcnames[func]);
X continue;
X }
X if (func != CLEFUN_BELL)
X fprintf(ofp,"key %s %s\n",rev_keyname(i),rev_funcnames[func]);
X }
X
X for (i = 0; i < kstr->tcapbuf_len;)
X {
X int j;
X
X j = *ascp++;
X if (j >= TCAP_COUNT)
X fprintf(stderr,"cled returned an unknown tcap_seq of {%s} assigned to 0x%02X\n",
X ascp,j);
X else
X {
X unchar *b,*s,c;
X
X s = inpbuf;
X *s = 0;
X b = ascp;
X while ((c = *b++) != 0)
X {
X if (c < ' ')
X {
X switch (c)
X {
X case '\t': strcat(s,"\\t"); break;
X case '\r': strcat(s,"\\r"); break;
X case '\n': strcat(s,"\\n"); break;
X case '\f': strcat(s,"\\f"); break;
X case '\v': strcat(s,"\\v"); break;
X default: sprintf(s,"\\%03o",c);
X }
X
X s += strlen(s);
X continue;
X }
X else if (c == '\\')
X {
X *s++ = '\\';
X *s++ = '\\';
X }
X else
X *s++ = c;
X
X *s = 0;
X }
X fprintf(ofp,"string %s \"%s\"\n",rev_tcapnames[j],inpbuf);
X }
X j = strlen(ascp) + 1;
X i += j + 1;
X ascp += j;
X }
X fclose(ofp);
X}
X
X#define OPT_OUTPUT 0x01
X#define OPT_ERROR 0x80
X
Xmain(argc,argv)
X int argc;
X unchar **argv;
X{
X int i,opts;
X unchar *kp,*ap,*abp;
X struct set_key *skp;
X
X for (opts = 0,i = 1; i < argc; ++i)
X {
X unchar *opt;
X
X opt = argv[i];
X if (*opt == '-')
X {
X if (i + 1 >= argc)
X {
X opts |= OPT_ERROR;
X fprintf(stderr,"%s option requires a parameter\n",opt);
X continue;
X }
X if (opt[1] == 'o')
X {
X opts |= OPT_OUTPUT;
X ++i;
X outfile = argv[i];
X continue;
X }
X opts |= OPT_ERROR;
X continue;
X }
X inpfile = argv[i];
X }
X
X if ((opts & OPT_ERROR) != 0)
X {
X fprintf(stderr,"Usage: %s [-o output_filename] [input_filename]\n",argv[0]);
X exit(1);
X }
X
X for (i = 0; i < CLEFUN_MAX; ++i)
X rev_funcnames[func_names[i].numb] = (unchar *) func_names[i].str;
X for (i = 0; i < TCAP_COUNT; ++i)
X rev_tcapnames[tcap_seq[i].numb] = (unchar *) tcap_seq[i].str;
X
X#ifdef NOISY
X fprintf(stderr,"stderr fildes = %d. isatty() = %d\n",fileno(stderr),
X isatty(fileno(stderr)));
X#endif
X
X if (!isatty(fileno(stderr)))
X {
X fprintf(stderr,"stderr is not a tty. Can't set discipline\n");
X exit(1);
X }
X
X if (ioctl(fileno(stderr),TCGETA,&tio) < 0)
X {
X perror("Error obtaining termio struct from stderr\n\t");
X exit(1);
X }
X
X cledp = open(cledfn,O_RDWR);
X if (cledp < 0)
X {
X fprintf(stderr,"cled not installed on the system\n");
X exit(1);
X }
X
X if (ioctl(cledp,LDGETS,&stats) < 0)
X {
X sprintf(inpbuf,"Error doing LDGETS ioctl to %s\n\t",cledfn);
X perror(inpbuf);
X exit(1);
X }
X close(cledp);
X
X if (stats.line == 0)
X {
X fprintf(stderr,"cled is not installed as a line discipline\n");
X exit(1);
X }
X
X#if 0
X if (stats.ledbufs <= stats.ledbufs_used ||
X stats.ttybufs <= stats.ttybufs_used)
X {
X fprintf(stderr,"No buffers available. ttybufs free = %d, ledbufs free = %d\n",
X stats.ttybufs - stats.ttybufs_used,stats.ledbufs - stats.ledbufs_used);
X exit(1);
X }
X#endif
X
X tio.c_line = stats.line;
X tio.c_lflag |= CLEDFLAGS;
X if (ioctl(fileno(stderr),TCSETA,&tio) < 0)
X {
X sprintf(inpbuf,"Error setting line discipline to %d\n\t",stats.line);
X perror(inpbuf);
X exit(1);
X }
X
X if ((opts & OPT_OUTPUT) != 0)
X make_output();
X
X read_setup();
X if (cols > 0)
X if (ioctl(fileno(stderr),LDSETCOLS,&cols) < 0)
X {
X perror("error setting # of columns in cled\n\t");
X fprintf(stderr,"columns %d\n",cols);
X exit(1);
X }
X
X if (buf != (unchar *) 0)
X {
X struct set_key old;
X
X old = *(struct set_key *) buf;
X if (ioctl(fileno(stderr),LDSETBF,buf) < 0)
X {
X perror("error setting key buf in cled\n\t");
X ioctl_error(&old);
X exit(1);
X }
X }
X
X return 0;
X}
END_OF_FILE
if test 18349 -ne `wc -c <'scled.c'`; then
echo shar: \"'scled.c'\" unpacked with wrong size!
fi
chmod +x 'scled.c'
# end of 'scled.c'
fi
if test -f 'space.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'space.c'\"
else
echo shar: Extracting \"'space.c'\" \(553 characters\)
sed "s/^X//" >'space.c' <<'END_OF_FILE'
X/*
X $Id: space.c,v 2.5 90/08/26 11:35:49 sw Exp $
X*/
X
X#include "config.h"
X
X#ifdef CLED
X
X#include "sys/types.h"
X#include "sys/tty.h"
X#include "sys/termio.h"
X#include "sys/cledio.h"
X#include "sys/cled.h"
X
X#if CLED_CNTLS != 1
X# include "ERROR: cled must have just one controller"
X#endif
X
X#if !MULTI_LB || !defined NCLEPROCS
X# undef NCLEPROCS
X# define NCLEPROCS 1
X#endif
X
Xint cle_ttys = {CLED_UNITS};
Xint cle_leds = {CLED_UNITS*NCLEPROCS};
X
Xstruct led_buf cle_buffers[CLED_UNITS];
Xstruct tty_buf cle_ttybuf[CLED_UNITS*NCLEPROCS];
X
X#endif
END_OF_FILE
if test 553 -ne `wc -c <'space.c'`; then
echo shar: \"'space.c'\" unpacked with wrong size!
fi
chmod +x 'space.c'
# end of 'space.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Piercarlo "Peter" Grandi | ARPA: pcg%uk.ac.aber.cs at nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg at cs.aber.ac.uk
--
Piercarlo "Peter" Grandi | ARPA: pcg%uk.ac.aber.cs at nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg at cs.aber.ac.uk
More information about the Alt.sources
mailing list