Line discipline part 2 of 4

Dave Shepperd shepperd at dms.UUCP
Fri Nov 10 06:36:42 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:42 PST 1989
# Contents:  cledinst cledinst.unix makefile makefile.unix cledsetup.c
#	cleddump.c cledac
 
echo x - cledinst
sed 's/^@//' > "cledinst" <<'@//E*O*F cledinst//'
# /bin/sh
#	@(#) cled.sh 1.1 89/06/07
#
#	cled installation script
#

PATH=/etc:/bin:/usr/bin

# error message function
error() {
    echo "\nError: $*" >&2
    return 1
}

# protection from interrupts while manipulating system files
copyfile () {
	trap "" 1 2 3 15
	cp $1 $2
	trap 'cleanup' 1 2 3 15
}

# prompt function
prompt () { 
    while echo "\n${mesg}$quit \c" >&2
    do
        read cmd
        case $cmd in
            Q|q)
                return 1
                ;;
            +x|-x)
                set $cmd
                ;;
            !*)
                eval `expr "$cmd" : "!\(.*\)"`
                ;;
            "") # "quit" is null when prompt is "press return to continue"
                [ -z "$quit" ] && return 0
                # if there is an argument use it as the default
                # else loop until cmd is set
                [ "$1" ] && { 
                    cmd=$1
                    return 0
                }
                error Invalid response
                ;;
            *)  return 0
                ;;
        esac
    done
}

# Prompt for yes or no answer - returns non-zero for no

getyn() {
	while	echo "\n$* (y/n/q) \c">&2
	do	read yn rest
		case $yn in
		     [yY]) return 0 		                  ;;
	        [nN]|[qQ]) return 1		                  ;;
		        *) echo "\nPlease answer y, n, or q" >&2  ;;
		esac
	done
}

# remove tmp files if interrupted

cleanup () {
	echo "\nInstallation exiting.\n" >&2
	trap '' 1 2 3 15
	rm -f /tmp/cled*$$ >&2
	cd $olddir
	exit 0
}

asklink () {
	getyn "\nYou must create a new kernel to $onoff cled.\n
Do you want to create a new kernel now?"  ||  {
		echo "cled will not be $insdeins on your system until you type:"
		echo "\n\tcd /usr/sys/conf; make\n"
		return 1
	}
}

rmcled() {
	cd /usr/sys/conf
	if grep cled master > /dev/null
	then 
		echo "Removing cled device from master..."
		./configure -d -c -m `./configure -j cled` > conflog 2>&1 || {
			error "configure failed to remove cled from master.
Check /usr/sys/conf/conflog for details".
			cleanup
		}
		rm -f conflog
	fi
	if grep cled.o link_xenix > /dev/null
	then 
		echo "Removing cled.o from link_xenix (old link_xenix is in link_xenix.00)..."
		awk '{sub("../io/cled.o",""); print;}' link_xenix > /tmp/cledlink$$ 2>&1 || {
			error "Error removing cled.o from link_xenix"
			cleanup
		}
		cp link_xenix link_xenix.00
		copyfile /tmp/cledlink$$ link_xenix
	fi
	if grep cled master > /dev/null
	then 
		echo "Removing cled discipline from master (old master is master.00)..."
		awk '$1 != "cled" { print }' master > /tmp/cledmaster$$ 2>&1 || {
			error "Error removing cled discipline from master"
			cleanup
		}
		cp master master.00
		copyfile /tmp/cledmaster$$ master
	fi
	if grep ../io/cled.o makefile > /dev/null
	then
		echo "Removing cled stuff from makefile (old makefile is in makefile.00)..."
		awk -f ${olddir}/makefile.rawk makefile > /tmp/cledmakefile$$ || {
			error "Error removing cled stuff from makefile.\n
See /tmp/cledmakefile$ for details"
			mv /tmp/cledmakefile$$ /tmp/cledmakefile\$
			cleanup
		}
		if grep cled /tmp/cledmakefile$$ > /dev/null
		then
			error "Unable to remove all references to cled in /usr/sys/makefile\n\
Please edit the makefile, remove all references to cled then rerun cledinst"
			cleanup
		fi
		cp makefile makefile.00
		copyfile /tmp/cledmakefile$$ makefile
	fi
	echo "Removing cled files from the system directories..."
	rm -f /usr/sys/io/cled.o /usr/include/cled_ioctl.h /usr/include/sys/cled_structs.h
	rm -f /usr/sys/io/cled.c /usr/sys/io/cledefault.c /dev/cled 
}

addcled() {
	cd $olddir
	echo "Making cled images..."
	rm -f makelog
	make all > makelog 2>&1 || {
		echo "Error making cled.o. See makelog for details"
		cleanup
	}
	rm -f makelog
	cd /usr/sys/conf
	if grep cled master > /dev/null
	then
	:
	else
		cledmaj=`./configure -j NEXTMAJOR`
		echo "Adding cled as major device ${cledmaj}..."
		./configure -c -a cledopen cledclose cledread cledwrite cledioctl cledinit\
			-m $cledmaj > conflog 2>&1 || {
			error "configure failed to add cled to master or xenixconf.
Check /usr/sys/conf/conflog for details".
			cleanup
		}
		rm -f conflog /dev/cled
		mknod /dev/cled c $cledmaj 0 > conflog 2>&1 || {
			error "Unable to mknod /dev/cled.
Check /usr/sys/conf/conflog for details".
			cleanup
		}
		chmod +rw /dev/cled
	fi
	if grep cled.o link_xenix > /dev/null
	then
	:
	else
		echo "Adding cled.o to link_xenix (link_xenix.01 has old link_xenix)..."
		cp link_xenix link_xenix.01
		trap "mv link_xenix.01 link_xenix; cleanup" 1 2 3 15
		cp link_xenix /tmp/cledlinka$$
		sed "s![ 	]c\.o!& ../io/cled.o!" /tmp/cledlinka$$ > /tmp/cledlinkb$$ || {
				error "Cannot edit link_xenix"
				cleanup
		}
		copyfile /tmp/cledlinkb$$ link_xenix
		trap 'cleanup' 1 2 3 15
		chmod 700 link_xenix
	fi
	if grep cleopen master > /dev/null
	then
	:
	else
		echo "Adding cled as line discipline to master (master.01 has old master)..."
		cp master master.01
		awk -f ${olddir}/master.awk master > /tmp/cledmaster$$ || {
			error "Error adding discipline line to master"
			cleanup
		}
		copyfile /tmp/cledmaster$$ master
	fi
	echo "copying the cled files to the appropriate directories..."
	cd $olddir
	cp cled.o /usr/sys/io
	cp cledsetup /usr/bin
}

makekernel() {
   if asklink
   then 
	echo "Making a new kernel..."
	cd /usr/sys/conf
	make > kmakelog 2>&1 || {
		echo "Error making the kernel. See /usr/sys/conf/kmakelog for details"
		cleanup
	}
	getyn "Do you want the newly created kernel to boot by default?" || {
		echo "\nBoot /usr/sys/conf/xenix to use cled"
		return 1
	}
	mv /xenix /xenix-
	cp /usr/sys/conf/xenix /xenix
   fi
}

# begin main part of program

trap 'cleanup' 1 2 3 15

olddir=`pwd`

while
    quit=" or enter q to quit:"
    mesg="\tcled installation program\n
	1. Add cled to the system
	2. Remove cled from the system
	
Select an option"
	do
		prompt || cleanup 
		maincmd=$cmd
  		case $maincmd in
      			1) # add cled to the system
       		  	   addcled 
			   onoff="enable" insdeins="installed"
			   makekernel
			   break
			   ;;
     		        2) # remove cled from the system
       		  	   rmcled
			   onoff="disable" insdeins="completely deinstalled"
			   makekernel
			   ;;
			*) echo "\nEnter 1, 2 or q" >&2 ;;
  		esac
	done
cleanup

@//E*O*F cledinst//
chmod u=rw,g=r,o=r cledinst
 
echo x - cledinst.unix
sed 's/^@//' > "cledinst.unix" <<'@//E*O*F cledinst.unix//'
# /bin/sh
#	@(#) cled.sh 1.1 89/06/07
#
#	cled installation script
#

PATH=/etc:/bin:/usr/bin

# error message function
error() {
    echo "\nError: $*" >&2
    return 1
}

# protection from interrupts while manipulating system files
copyfile () {
	trap "" 1 2 3 15
	cp $1 $2
	trap 'cleanup' 1 2 3 15
}

# prompt function
prompt () { 
    while echo "\n${mesg}$quit \c" >&2
    do
        read cmd
        case $cmd in
            Q|q)
                return 1
                ;;
            +x|-x)
                set $cmd
                ;;
            !*)
                eval `expr "$cmd" : "!\(.*\)"`
                ;;
            "") # "quit" is null when prompt is "press return to continue"
                [ -z "$quit" ] && return 0
                # if there is an argument use it as the default
                # else loop until cmd is set
                [ "$1" ] && { 
                    cmd=$1
                    return 0
                }
                error Invalid response
                ;;
            *)  return 0
                ;;
        esac
    done
}

# Prompt for yes or no answer - returns non-zero for no

getyn() {
	while	echo "\n$* (y/n/q) \c">&2
	do	read yn rest
		case $yn in
		     [yY]) return 0 		                  ;;
	        [nN]|[qQ]) return 1		                  ;;
		        *) echo "\nPlease answer y, n, or q" >&2  ;;
		esac
	done
}

# remove tmp files if interrupted

cleanup () {
	echo "\nInstallation exiting.\n" >&2
	trap '' 1 2 3 15
	rm -f /tmp/cled*$$ >&2
	cd $olddir
	exit 0
}

asklink () {
	getyn "\nYou must create a new kernel to $onoff cled.\n
Do you want to create a new kernel now?"  ||  {
		echo "cled will not be $insdeins on your system until you type:"
		echo "\n\tcd /etc/conf/cf.d; ./link_unix\n"
		return 1
	}
}

rmcled() {
	cd /etc/conf/cf.d
	if ./configure -j cled
	then
		echo "Removing cled device from device tables..."
		./configure -d -c -m `./configure -j cled` > conflog 2>&1 || {
			error "configure failed to remove cled from conf files.
Check /etc/conf/cf.d/conflog for details".
			cleanup
		}
		rm -f conflog /dev/cled
	fi
	if grep _cled_ /etc/conf/pack.d/kernel/space.c > /dev/null
	then
		cd /etc/conf/pack.d/kernel
		echo "Removing cled from kernel/space.c..."
		awk -f ${olddir}/space.c.rawk space.c > /tmp/cledspace$$ || {
			error "awk had error removing discipline from space.c"
			cleanup
		}
		copyfile space.c space.cled
		copyfile /tmp/cledspace$$ space.c
	fi
	echo "Removing cled files from the system directories..."
	rm -f -r /etc/conf/pack.d/cled
	rm -f /usr/bin/cledsetup /dev/cled
}

addcled() {
	if [ -f cled.c ] 
	then
	:
	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
	echo "Making cled images..."
	rm -f makelog
	make all > makelog 2>&1 || {
		echo "Error making cled.o. See makelog for details"
		cleanup
	}
	rm -f makelog
	cd /etc/conf/cf.d
	if ./configure -j cled
	then
	:
	else
		cledmaj=`./configure -j NEXTMAJOR`
		echo "Adding cled as major device ${cledmaj}..."
		./configure -c -a cledopen cledclose cledread cledwrite cledioctl \
			cledinit -h cled -Y -m $cledmaj > conflog 2>&1 || {
			error "configure failed to add cled to kernel/space.c
Check /etc/conf/cf.d/conflog for details".
			cleanup
		}
		rm -f conflog /dev/cled
		mknod /dev/cled c $cledmaj 0 > conflog 2>&1 || {
			error "Unable to mknod /dev/cled.
Check /etc/conf/cf.d/conflog for details".
			cleanup
		}
		chmod +rw /dev/cled
	fi
	if grep _cled_ /etc/conf/pack.d/kernel/space.c > /dev/null
	then
	:
	else
		cd /etc/conf/pack.d/kernel
		echo "Adding cled as line discipline to kernel/space.c (space.nocled has old space.c)..."
		awk -f ${olddir}/space.c.awk space.c > /tmp/cledspace$$ || {
			error "AWK had error adding discipline line to space.c"
			cleanup
		}
		copyfile space.c space.nocled
		copyfile /tmp/cledspace$$ space.c
	fi
	echo "copying the cled files to the appropriate directories..."
	cd $olddir
	rm -r -f /etc/conf/pack.d/cled
	mkdir /etc/conf/pack.d/cled
	cp cled.o /etc/conf/pack.d/cled/Driver.o
	cp cledsetup /bin
	cp cleddump /bin
}

makekernel() {
   if asklink
   then 
	echo "Making a new kernel..."
	cd /etc/conf/cf.d
	./link_unix > kmakelog 2>&1 || {
		echo "Error making the kernel. See /etc/conf/cf.d/kmakelog for details"
		cleanup
	}
   fi
}

# begin main part of program

trap 'cleanup' 1 2 3 15

olddir=`pwd`

while
    quit=" or enter q to quit:"
    mesg="\tcled installation program\n
	1. Add cled to the system
	2. Remove cled from the system
	
Select an option"
	do
		prompt || cleanup 
		maincmd=$cmd
  		case $maincmd in
      			1) # add cled to the system
       		  	   addcled 
			   onoff="enable" insdeins="installed"
			   makekernel
			   break
			   ;;
     		        2) # remove cled from the system
       		  	   rmcled
			   onoff="disable" insdeins="completely deinstalled"
			   makekernel
			   ;;
			*) echo "\nEnter 1, 2 or q" >&2 ;;
  		esac
	done
cleanup

@//E*O*F cledinst.unix//
chmod u=rw,g=r,o=r cledinst.unix
 
echo x - makefile
sed 's/^@//' > "makefile" <<'@//E*O*F makefile//'
KFLAGS	 = -DM_KERNEL -DVPIX
CFLAGS   = -O -M3 -Zp4 -Me 
#CFLAGS   = -Od -g -M3 -Zp4 -Me 
ATFLAGS = -DQ_AT
CONFFLAGS = -DSYSINFO

CC = cc

all: cledsetup cleddump cled.o
	:

cled.c : 
	sh mkcledc

cled.o: cled.c cled_ioctl.h cled_structs.h
	$(CC) $(CFLAGS) $(KFLAGS) $(CONFFLAGS) -c cled.c

cled: cled.c cled_ioctl.h cled_structs.h
	$(CC) $(CFLAGS) -o cled cled.c

cledsetup: cledsetup.c cled_ioctl.h
	$(CC) $(CFLAGS) -o cledsetup cledsetup.c
	
cleddump: cleddump.c cled_ioctl.h cled_structs.h
	$(CC) $(CFLAGS) $(KFLAGS) -o cleddump cleddump.c

@//E*O*F makefile//
chmod u=rw,g=r,o=r makefile
 
echo x - makefile.unix
sed 's/^@//' > "makefile.unix" <<'@//E*O*F makefile.unix//'
KFLAGS	 = -DM_KERNEL -DVPIX
CFLAGS   = -O -M3 -Zp4 -Me -DM_UNIX
#CFLAGS   = -Od -g -M3 -Zp4 -Me 
ATFLAGS = -DQ_AT
CONFFLAGS = -DSYSINFO

CC = cc

all: cledsetup cleddump cled.o
	:

cled.c: 
	sh mkcledc

cled.o: cled.c cled_ioctl.h cled_structs.h
	$(CC) $(CFLAGS) $(KFLAGS) $(CONFFLAGS) -c cled.c

cled: cled.c cled_ioctl.h cled_structs.h
	$(CC) $(CFLAGS) -o cled cled.c

cledsetup: cledsetup.c cled_ioctl.h
	$(CC) $(CFLAGS) -o cledsetup cledsetup.c
	
cleddump: cleddump.c cled_ioctl.h cled_structs.h
	$(CC) $(CFLAGS) $(KFLAGS) -o cleddump cleddump.c

@//E*O*F makefile.unix//
chmod u=rw,g=r,o=r makefile.unix
 
echo x - cledsetup.c
sed 's/^@//' > "cledsetup.c" <<'@//E*O*F cledsetup.c//'
#include <sys/types.h>
#include <sys/tty.h>
#if defined(M_UNIX)
#include <sys/termio.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "cled_ioctl.h"

char *buf;
char inpbuf[256];
struct termio tio;
extern char *malloc(),*getenv();

FILE *ifp;
int cledp;

char *cledfn = "/dev/cled";

struct cle_stats stats;

struct items {
   int numb;
   char *str;
} ansi_seq[] = {
      { ANSI_UP,"up" },
      { ANSI_CLREOL,"clreol" },
      { ANSI_CLRLINE,"clrline" },
      { ANSI_SETINV,"setinv" },
      { ANSI_SETNORM,"setnorm" },
      { ANSI_SAVE, "save" },
      { ANSI_RESTORE, "restore" },
      { ANSI_MSGEOF, "msgeof" },
      { ANSI_MSGINTR, "msgintr" },
      { ANSI_MSGQUIT, "msgquit" },
      { ANSI_SETUP, "setup" },
      { ANSI_80COL, "80col" },
      { ANSI_132COL, "132col" },
      0
};

struct items key_names[] = {
   { CLEKEY_NULL, "clt_@" },
   { CLEKEY_CTLA, "ctl_A" },
   { CLEKEY_CTLB, "ctl_B" },
   { CLEKEY_CTLC, "ctl_C" },
   { CLEKEY_CTLD, "ctl_D" },
   { CLEKEY_CTLE, "ctl_E" },
   { CLEKEY_CTLF, "ctl_F" },
   { CLEKEY_CTLG, "ctl_G" },
   { CLEKEY_CTLH, "ctl_H" },
   { CLEKEY_CTLI, "ctl_I" },
   { CLEKEY_CTLJ, "ctl_J" },
   { CLEKEY_CTLK, "ctl_K" },
   { CLEKEY_CTLL, "ctl_L" },
   { CLEKEY_CTLM, "ctl_M" },
   { CLEKEY_CTLN, "ctl_N" },
   { CLEKEY_CTLO, "ctl_O" },
   { CLEKEY_CTLP, "ctl_P" },
   { CLEKEY_CTLQ, "ctl_Q" },
   { CLEKEY_CTLR, "ctl_R" },
   { CLEKEY_CTLS, "ctl_S" },
   { CLEKEY_CTLT, "ctl_T" },
   { CLEKEY_CTLU, "ctl_U" },
   { CLEKEY_CTLV, "ctl_V" },
   { CLEKEY_CTLW, "ctl_W" },
   { CLEKEY_CTLX, "ctl_X" },
   { CLEKEY_CTLY, "ctl_Y" },
   { CLEKEY_CTLZ, "ctl_Z" },
   { CLEKEY_CTLa, "ctl_[" },
   { CLEKEY_CTLb, "ctl_\\" },
   { CLEKEY_CTLc, "ctl_]" },
   { CLEKEY_CTLd, "ctl_^" },
   { CLEKEY_CTLe, "ctl__" },
   { CLEKEY_UP , "up" },
   { CLEKEY_DOWN, "down" },
   { CLEKEY_RIGHT, "right" },
   { CLEKEY_LEFT, "left" },
   { CLEKEY_ENTER, "enter" },
   { CLEKEY_PF1, "pf1" },
   { CLEKEY_PF2, "pf2" },
   { CLEKEY_PF3, "pf3" },
   { CLEKEY_PF4, "pf4" },
   { CLEKEY_KPCOMMA, "comma" },
   { CLEKEY_KPMINUS, "minus" },
   { CLEKEY_DOT, "period" },
   { CLEKEY_KP0, "0" },
   { CLEKEY_KP1, "1" },
   { CLEKEY_KP2, "2" },
   { CLEKEY_KP3, "3" },
   { CLEKEY_KP4, "4" },
   { CLEKEY_KP5, "5" },
   { CLEKEY_KP6, "6" },
   { CLEKEY_KP7, "7" },
   { CLEKEY_KP8, "8" },
   { CLEKEY_KP9, "9" },
   { CLEKEY_KP0, "kp0" },
   { CLEKEY_KP1, "kp1" },
   { CLEKEY_KP2, "kp2" },
   { CLEKEY_KP3, "kp3" },
   { CLEKEY_KP4, "kp4" },
   { CLEKEY_KP5, "kp5" },
   { CLEKEY_KP6, "kp6" },
   { CLEKEY_KP7, "kp7" },
   { CLEKEY_KP8, "kp8" },
   { CLEKEY_KP9, "kp9" },
   { CLEKEY_DEL, "del" },
   { CLEKEY_DEL, "DEL" },
   { CLEKEY_HOME, "home" },
   { CLEKEY_END, "end" },
   { CLEKEY_INSERT, "insert" },
   { CLEKEY_DEL, "delete" },
   { CLEKEY_PGUP, "page_up" },
   { CLEKEY_PGDN, "page_down" },
   { CLEKEY_F1, "f1" },
   { CLEKEY_F2, "f2" },
   { CLEKEY_F3, "f3" },
   { CLEKEY_F4, "f4" },
   { CLEKEY_F5, "f5" },
   { CLEKEY_F6, "f6" },
   { CLEKEY_F7, "f7" },
   { CLEKEY_F8, "f8" },
   { CLEKEY_F9, "f9" },
   { CLEKEY_F10, "f10" },
   { CLEKEY_F11, "f11" },
   { CLEKEY_F12, "f12" },
   { CLEKEY_F13, "f13" },
   { CLEKEY_F14, "f14" },
   { CLEKEY_F15, "f15" },
   { CLEKEY_F16, "f16" },
   { CLEKEY_F17, "f17" },
   { CLEKEY_F18, "f18" },
   { CLEKEY_F19, "f19" },
   { CLEKEY_F20, "f20" },
   { CLEKEY_NULL, "null" },
   {0,0}
};

struct items func_names[] = {
   { CLEFUN_INSERT, "insert" },
   { CLEFUN_INSERT, "overstrike" },
   { CLEFUN_GOTOBOL, "goto_bol" },
   { CLEFUN_GOTOEOL, "goto_eol" },
   { CLEFUN_DELWLFT, "del_word_left" },
   { CLEFUN_DELWRIT, "del_word_right" },
   { CLEFUN_DELBOL, "del_to_bol" },
   { CLEFUN_DELEOL, "del_to_eol" },
   { CLEFUN_CURSL, "cursor_left" },
   { CLEFUN_CURSR, "cursor_right" },
   { CLEFUN_DELCLFT, "del_char_left" },
   { CLEFUN_DELCRIT, "del_char_right" },
   { CLEFUN_REFRESH, "refresh" },
   { CLEFUN_PREVIOUS, "previous" },
   { CLEFUN_NEXT, "next" },
   { CLEFUN_FIND, "find" },
   { CLEFUN_NEWLINE, "newline" },
   { CLEFUN_ESCAPE, "superquote" },
   { CLEFUN_132, "132_80" },
   { CLEFUN_NOP, "nop" },
   { CLEFUN_ADVANCE, "advance" },
   { CLEFUN_BACKUP, "backup" },
   { CLEFUN_SKIPW, "skip_word" },
   { CLEFUN_SKIPC, "skip_char" },
   { CLEFUN_SKIPL, "skip_line" },
   { CLEFUN_BELL, "bell" },
   { CLEFUN_SKIPWR, "skip_word_right" },
   { CLEFUN_SKIPWL, "skip_word_left" },
   { CLEFUN_SKIPTOL, "skip_to_xol" },
   { CLEFUN_PURGE, "purge" },
   {0,0}
};

char *rev_keynames[CLEKEY_MAX];
char *rev_funcnames[CLEFUN_MAX];
char *rev_ansinames[ANSI_COUNT];
char *set_ansinames[ANSI_COUNT];
char *ansi_defs[ANSI_COUNT];

struct cle_stats stats;
int line = 0,errors = 0;
char delim[] = " \t\n";
char *pathptrs[4];

#define NULLP ((unsigned char *)0)
#define ACC_EXISTS  0
#define ACC_EXECUTE 1
#define ACC_WRITE   2
#define ACC_READ    4

/****************************************************************************************
 * get_pathname is a function that takes as input an array of char *'s which are presumed
 * to be path names and a char * which is assumed to be a filename. It builds a real
 * filename by gluing each of the path names successively to the filename and doing
 * an access test on the composite name. It returns a pointer to the composite string
 * if the file is accessable otherwise it returns null.
 */

   	char *get_pathname(paths,filename,amode)
   	char **paths,*filename;
   	int amode;
/*
 * At entry:
 *	paths - ptr to NULLP terminated array of char pointers each pointing to
 *		null terminated pathname string.
 *	filename - ptr to filename string
 *	amode - access mode which to use to test according to the following:
 *		00 - check for file existance
 *		01 - check for execute (search)
 *		02 - check for write
 *		04 - check for read
 * At exit:
 *	returns ptr to composite string from malloc'd memory if file accessable
 *	else returns NULL.
 */
{
   char *s;
   int fnlen;
   fnlen = strlen(filename)+1;
   if (filename[0] == '/' ||
       (filename[0] == '.' && filename[1] == '/' ||
      			     (filename[1] == '.' && filename[2] == '/'))) {
      paths = NULLP;		/* don't add anything if path already attached */
   }      
   while (paths != NULLP && *paths != NULLP) {
      int plen;
      plen = strlen(*paths);	/* get length of this path */
      s = malloc(plen+fnlen);	/* get some space (fnlen includes the terminating null) */
      strcpy(s,*paths);		/* stick in the path name */
      strcat(s,filename);	/* glue on the filename */
      if (access(s,amode) == 0) return s; /* if file present, we're done */
      free(s);			/* else we're done with the memory */
      ++paths;			/* bump ptr to next path */
   }
   if (access(filename,amode) == 0) { /* check the filename without a path */
      s = malloc(fnlen);
      strcpy(s,filename);
      return s;
   }
   return NULLP;
}

int show_error(what,token)
char *what,*token;
{
    if (token == 0) {
       fprintf(stderr,"Missing %s on line %d\n",what,line);
    } else {
       fprintf(stderr,"Unknown %s {%s} on line %d\n",what,token,line);
    }
    ++errors;
}

char *outfile=0;
char *inpfile=0;

#ifdef NOISY
dump_text(ptr,len)
char *ptr;
int len;
{
   int i,j;
   char *l;

   while(len>0) {
      l = ptr;
      j = (len > 32) ? 32 : len;
      for (i=0;i<j;++i) fprintf(stderr,"%02X ",*(l+i));
      fputs("\n",stderr);
      for (i=0;i<j;++i) fprintf(stderr," %c ",(*(l+i) > ' ') ? *(l+i) : '.');
      fputs("\n",stderr);
      ptr += j;
      len -= j;
   }
}
#endif

void ioctl_error(old)
struct set_key *old;
{
   int key,kie,func;
   unsigned char *kp;
   struct set_key *skp;

   skp = (struct set_key *)buf;			/* point to key struct */
   kp = (char *)(skp+1);			/* point to key space */
   kp += skp->kdbuf_len*2;			/* skip to key in error or ansibuf */
   if (old->kdbuf_len != skp->kdbuf_len) {
      kie = *kp++;
      func = *kp++;
      fprintf(stderr,"Error setting Key 0x%02X (%s) to func 0x%02X (%s)\n",
      		kie,kie<CLEKEY_MAX?rev_keynames[kie]:"",
      		func,func<CLEFUN_MAX?rev_funcnames[func]:"");
   } else if (old->ansibuf_len != skp->ansibuf_len) {
      int i;
      unsigned char *t,*s;
      i = strlen(kp)+1;
      if ((t = malloc(i)) == (char *)0) {
	 fprintf(stderr,"Error malloc'ing %d bytes during error report for set_ansi failure\n",
	 	i);
	 return;
      }
      kie = *kp++;
      for (s=t;i>0;--i,++kp) {
	 *s++ = (*kp >= ' ' && *kp < 0177) ? *kp : '.';
      }	 
      *s = 0;
      fprintf(stderr,"Error setting string 0x%02X (%s) to \"%s\"\n",
      		kie,kie<ANSI_COUNT?rev_ansinames[kie]:"",t);
      free(t);
   } else {
      fprintf(stderr,"Error %d setting keys/ansi strings in cled\n",errno);
      fprintf(stderr,"before modes = %08X, kdbuf_len = %d, ansibuf_len = %d\n",
      		old->modes,old->kdbuf_len,old->ansibuf_len);
      fprintf(stderr,"after  modes = %08X, kdbuf_len = %d, ansibuf_len = %d\n",
      		skp->modes,skp->kdbuf_len,skp->ansibuf_len);
   }
   return;
}

void read_setup()
{
   int i,anslen=0;
   char *kp,*ap,*abp,*ifn;
   struct set_key *skp;
   if (inpfile == NULLP) inpfile = ".cledrc";
   pathptrs[0] = "./";
   ap = getenv("CLED");
   if (ap != NULLP && (i=strlen(ap)) > 0) {
      if (ap[i-1] != '/') {
	 kp = malloc(strlen(ap)+2);
	 strcpy(kp,ap);
	 strcat(kp,"/");
	 ap = kp;
      }
   }
   pathptrs[1] = ap;
   ap = getenv("HOME");
   if (ap != NULLP && (i=strlen(ap)) > 0) {
      if (ap[i-1] != '/') {
	 kp = malloc(strlen(ap)+2);
	 strcpy(kp,ap);
	 strcat(kp,"/");
	 ap = kp;
      }
   }
   pathptrs[2] = ap;
   ifn = get_pathname(pathptrs,inpfile,ACC_READ);
   if (ifn == NULLP) {
      if (buf != 0) free(buf);
      buf = NULLP;
      return;
   }
   ifp = fopen(ifn,"r");		/* open config file */
   if (ifp == 0) {
      sprintf(inpbuf,"Unable to open input: %s\n\t",ifn);
      perror(inpbuf);
      exit(1);
   }
   ansi_defs[ANSI_UP] = ANSI_UP_STR;		/* up-arrow */
   ansi_defs[ANSI_CLREOL] = ANSI_CLREOL_STR;	/* clear to eol */
   ansi_defs[ANSI_CLRLINE] = ANSI_CLRLINE_STR;	/* clear whole line */
   ansi_defs[ANSI_SETINV] = ANSI_SETINV_STR;	/* set inverse video */
   ansi_defs[ANSI_SETNORM] = ANSI_SETNORM_STR;	/* set normal video */
   ansi_defs[ANSI_SAVE] = ANSI_SAVE_STR;	/* save cursor pos and attr's */
   ansi_defs[ANSI_RESTORE] = ANSI_RESTORE_STR;	/* restore cursor pos and attr's */
   ansi_defs[ANSI_MSGEOF] = ANSI_MSGEOF_STR;	/* EOF message */
   ansi_defs[ANSI_MSGINTR] = ANSI_MSGINTR_STR; /* INTR message */
   ansi_defs[ANSI_MSGQUIT] = ANSI_MSGQUIT_STR; /* QUIT message */
   ansi_defs[ANSI_SETUP] = ANSI_SETUP_STR;	/* set terminal to app mode */
   ansi_defs[ANSI_80COL] = ANSI_80COL_STR;	/* set to 80 cols */
   ansi_defs[ANSI_132COL] = ANSI_132COL_STR;	/* set to 132 cols */
   i = 256+sizeof(struct set_key)+CLEKEY_MAX*2;
   buf = (char *)malloc(i*2);
   if (buf == 0) {
      fprintf(stderr,"Unable to allocate %d bytes\n",i);
      exit(1);
   }
   skp = (struct set_key *)buf;			/* point to key struct */
   skp->kdbuf_len = 0;
   skp->ansibuf_len = 0;
   skp->modes = 0;
   kp = (char *)(skp+1);			/* point to key space */
   abp = ap = kp + CLEKEY_MAX*2;
   while(fgets(inpbuf,sizeof(inpbuf),ifp) != NULL) {
      char *tok1,*tok2,c;
      extern char *strtok();
      ++line;
      tok1 = strtok(inpbuf,delim);
      if (tok1 == 0) continue;
      if (strcmp(tok1,"mode") == 0) {
	 tok1 = strtok((char *)0,delim);
	 if (tok1 == 0) {
	    show_error("mode",tok1);
	    continue;
	 }
	 if (strcmp(tok1,"insert") == 0) {
	    skp->modes |= CLEMODE_INSERT;
	    continue;
	 }
	 if (strcmp(tok1,"overstrike") ==0) {
	    skp->modes |= CLEMODE_OVER;
	    continue;
	 }
	 if (strcmp(tok1,"80") == 0) {
	    skp->modes |= CLEMODE_80;
	    continue;
	 }
	 if (strcmp(tok1,"132") == 0) {
	    skp->modes |= CLEMODE_132;
	    continue;
	 }
	 show_error("mode",tok1);
	 continue;
      }
      if (strcmp(tok1,"key") == 0) {
	 int key,func;
	 tok1 = strtok((char *)0,delim);
	 if (tok1 == 0) {
	    show_error("keyname",tok1);
	    continue;
	 }
	 for (key=0;key_names[key].str != 0;++key) {
	    if (strcmp(key_names[key].str,tok1) == 0) break;
	 }
	 if (key_names[key].str == 0) {
	    show_error("keyname",tok1);
	    continue;
	 }
	 key = key_names[key].numb;
	 tok1 = strtok((char *)0,delim);
	 if (tok1 ==0) {
	    show_error("function name",tok1);
	    continue;
	 }
	 for (func=0;func_names[func].numb>0;++func) {
	    if (strcmp(func_names[func].str,tok1) == 0) break;
	 }
	 if (func_names[func].numb == 0) {
	    show_error("function name",tok1);
	    continue;
	 }
	 skp->kdbuf_len += 1;
	 *kp++ = key;
	 *kp++ = func_names[func].numb;
	 continue;
      }
      if (strcmp(tok1,"string") == 0) {
	 int ans;
	 unsigned char *s;
	 tok1 = strtok((char *)0,delim);
	 if (tok1 == 0) {
	    show_error("string name",tok1);
	    continue;
	 }
	 for (ans=0;ansi_seq[ans].str != 0;++ans) {
	    if (strcmp(ansi_seq[ans].str,tok1) == 0) break;
	 }
	 if (ansi_seq[ans].str == 0) {
	    show_error("string name",tok1);
	    continue;
	 }
	 tok1 = strtok((char *)0,"\"\r\n");
	 if (set_ansinames[ans] != NULLP) {
	    anslen -= strlen(set_ansinames[ans])-1;
	    if (anslen < 0) anslen = 0;
	    free(set_ansinames[ans]);
	 }
	 if (tok1 != NULLP) {
	    s = set_ansinames[ans] = malloc(strlen(tok1)+1);
	    if (s == NULLP) {
	       fprintf(stderr,"Unable to allocate %d bytes of mem\n",
	       		strlen(tok1)+1);
	       exit(1);
	    }
	    while(*tok1) {
	       unsigned char c,*tp;
	       c = *s++ = *tok1++;
	       if (c == '\\') {
		  int val;
                  tp = tok1-1;
		  switch ((c= *tok1++)) {
		     case 't': val = '\t'; break;
		     case 'r': val = '\r'; break;
		     case 'n': val = '\n'; break;
		     case 'f': val = '\f'; break;
		     case 'v': val = '\v'; break;
		     case '0': 
			if (*tok1 < '0' || *tok1 > '7') {
			   val = 0;
       			   fprintf(stderr,"Warning: null in string on line %d\n",line);
			   break;
			}
		     case '1':
		     case '2':
		     case '3': {
			val = (c -'0') << 6;
			if (*tok1 < '0' || *tok1 > '7') {
			   show_error("string constant",tp);
			   break;
			}
			val |= (*tok1++ - '0') << 3;
			if (*tok1 < '0' || *tok1 > '7') {
			   show_error("string constant",tp);
			   break;
			}
			val |= *tok1++ - '0';
			break;
		     }
		     default: {
			val = c;
		     }
		  }			/* -- switch */
		  *(s-1) = val;
	       }			/* -- if '\' */
	    }				/* -- while (*tok1) */
	    *s++ = 0;			/* null terminate it */
	    anslen += s-set_ansinames[ans];
	 } else {			/* -+ if (tokp != 0) */
	    s = set_ansinames[ans] = malloc(1);
	    if (s == NULLP) {
	       fprintf(stderr,"Unable to allocate 1 byte");
	       exit(1);
	    }
	    *s = 0;
	    anslen += 1;
	 }
	 continue;
      }					/* -- if (tok1 == "ansi") */
      show_error("keyword",tok1);
   }					/* -- while (fgets != 0) */
   if (anslen > stats.ansisize) {	/* too long */
      fprintf(stderr,"Error: Total length of all strings is greater than %d\n",
      		stats.ansisize);
      exit(1);
   }
   if (anslen != 0) {			/* if there's some ascii strings */
      char *bp;
      bp = buf+sizeof(struct set_key)+skp->kdbuf_len*2;
      skp->ansibuf_len = 0;
      for (i=0;i<sizeof(set_ansinames)/sizeof(char *);++i) {
	 if (set_ansinames[i] != NULLP) {
	    if (strcmp(ansi_defs[i],set_ansinames[i]) != 0) {
	       int sln;
	       *bp++ = i;
	       strcpy(bp,set_ansinames[i]);
	       sln = strlen(bp)+1;
	       bp += sln;
	       skp->ansibuf_len += sln+1;
	    }
	    free(set_ansinames[i]);
	    set_ansinames[i] = NULLP;
	 }
      }
#ifdef NOISY
      fprintf(stderr,"Found %d bytes of ascii defines:\n",skp->ansibuf_len);
      bp = buf+sizeof(struct set_key)+skp->kdbuf_len*2;
      dump_text(bp,skp->ansibuf_len);
#endif
   }
#ifdef NOISY
   fprintf(stderr,"Found modes = %02X, %d key defines, %d bytes of ansi defines and %d errors\n",
   	skp->modes,skp->kdbuf_len,skp->ansibuf_len,errors);
#endif
   return;
}

void make_output()
{
   int i;
   unsigned char *bp,*kp,*ascp;
   FILE *ofp;
   struct set_key *kstr;
   ofp = fopen(outfile,"w");
   if (ofp == 0) {
      sprintf(inpbuf,"Unable to open %s for write\n\t",outfile);
      perror(inpbuf);
      exit(1);
   }
   i = 256+sizeof(struct set_key)+CLEKEY_MAX*2;
   bp = malloc(i);
   if (ioctl(stdout->_file,LDGETBF,bp) < 0) {
      perror("error getting key buf from cled\n\t");
      exit(1);
   }
   kstr = (struct set_key *)bp;
   kp = bp+sizeof(struct set_key);
   ascp = kp+kstr->kdbuf_len;
#ifdef NOISY
   fprintf(stderr,"kstr=%08X, kp=%08X, ascp=%08X, key_len=%d, asc_len=%d\n",
   	kstr,kp,ascp,kstr->kdbuf_len,kstr->ansibuf_len);
   dump_text(ascp,kstr->ansibuf_len);
#endif
   fprintf(ofp,"mode %s\n",(kstr->modes&CLEMODE_INSERT) ? "insert" : "overstrike");
   fprintf(ofp,"mode %s\n",(kstr->modes&CLEMODE_80) ? "80" : "132");
   for (i=0;i<kstr->kdbuf_len;++i) {
      int func,j;
      func = *kp++;
      if (func == 0) continue;
      if (func >= CLEFUN_MAX) {
	 fprintf(stderr,"cled returned an unknown function of 0x%02X assigned to key 0x%02X\n",
	 	func,i);
	 continue;
      }
      if (i >= CLEKEY_MAX) {
	 fprintf(stderr,"cled returned unknown key 0x%02X assigned to function %s\n",
      		i,rev_funcnames[func]);
	 continue;
      }
      fprintf(ofp,"key %s %s\n",rev_keynames[i],rev_funcnames[func]);
   }
   for (i=0;i<kstr->ansibuf_len;) {
      int j;
      j = *ascp++;
      if (j >= ANSI_COUNT) {
	 fprintf(stderr,"cled returned an unknown ansi_seq of {%s} assigned to 0x%02X\n",
	 	ascp,j);
      } else {
	 unsigned char *b,*s,c;
	 s = inpbuf;
         *s = 0;
         b = ascp;
	 while ((c = *b++) != 0) {
	    if (c < ' ') {
	       switch(c) {
		  case '\t': strcat(s,"\\t"); break;
		  case '\r': strcat(s,"\\r"); break;
		  case '\n': strcat(s,"\\n"); break;
		  case '\f': strcat(s,"\\f"); break;
		  case '\v': strcat(s,"\\v"); break;
		  default: sprintf(s,"\\%03o",c); break;
	       }
	       s += strlen(s);
	       continue;
	    } else if (c == '\\') {
	       *s++ = '\\';
	       *s++ = '\\';
	    } else {
	       *s++ = c;
	    }
	    *s = 0;
	 }
	 fprintf(ofp,"string %s \"%s\"\n",rev_ansinames[j],inpbuf);
      }
      j = strlen(ascp)+1;
      i += j+1;
      ascp += j;
   }
   fclose(ofp);
}

#define OPT_OUTPUT 0x01
#define OPT_ERROR  0x80

main(argc,argv)
int argc;
char **argv;
{
   int i,opts;
   char *kp,*ap,*abp;
   struct set_key *skp;
   for (opts=0,i=1;i<argc;++i) {
      char *opt;
      opt = argv[i];
      if (*opt == '-') {		/* if we've got an option */
	 if (i+1 >= argc) {
	    opts |= OPT_ERROR;		/* option nfg */
	    fprintf(stderr,"%s option requires a parameter\n",opt);
	    continue;
	 }
	 if (opt[1] == 'o') {		/* if output */
	    opts |= OPT_OUTPUT;
	    ++i;			/* goto next parameter */
	    outfile = argv[i];		/* save output filename */
	    continue;
	 }
	 opts |= OPT_ERROR;
	 continue;
      }
      inpfile = argv[i];
   }
   if ((opts&OPT_ERROR) != 0) {
      fprintf(stderr,"Useage: %s [-o output_filename] [input_filename]\n",argv[0]);
      exit(1);
   }
   for (i=0;i<sizeof(key_names)/sizeof(struct items)-1;++i) {
      rev_keynames[key_names[i].numb] = key_names[i].str;
   }   
   for (i=0;i<CLEFUN_MAX;++i) {
      rev_funcnames[func_names[i].numb] = func_names[i].str;
   }   
   for (i=0;i<ANSI_COUNT;++i) {
      rev_ansinames[ansi_seq[i].numb] = ansi_seq[i].str;
   }   
#ifdef NOISY
   fprintf(stderr,"stdout fildes = %d. isatty() = %d\n", stdout->_file,
   	isatty(stdout->_file));
#endif
   if(!isatty(stdout->_file)) {
      fprintf(stderr,"stdout is not a tty. Can't set discipline\n");
      exit(1);
   }
   if (ioctl(stdout->_file,TCGETA,&tio) < 0) {
      perror("Error obtaining termio struct from stdout\n\t");
      exit(1);
   }
   cledp = open(cledfn,O_RDWR);
   if (cledp < 0) {
      fprintf(stderr,"cled not installed on the system\n");
      exit(1);
   }
   if (ioctl(cledp,LDGETS,&stats) < 0) {
      sprintf(inpbuf,"Error doing LDGETS ioctl to %s\n\t",cledfn);
      perror(inpbuf);
      exit(1);
   }
   close(cledp);
   if (stats.line == 0) {
      fprintf(stderr,"cled is not installed as a line discipline\n");
      exit(1);
   }
#if 0
   if (stats.ledbufs <= stats.ledbufs_used ||
        stats.ttybufs <= stats.ttybufs_used) {
      fprintf(stderr,"No buffers available. ttybufs free = %d, ledbufs free = %d\n",
      	stats.ttybufs-stats.ttybufs_used,stats.ledbufs-stats.ledbufs_used);
      exit(1);
   }
#endif
   tio.c_line = stats.line;		/* select a new discipline */
   tio.c_lflag |= ICANON|ECHO|ECHOE|ECHOK;	/* enable all of it */
   if (ioctl(stdout->_file,TCSETA,&tio) < 0) {
      sprintf(inpbuf,"Error setting line discipline to %d\n\t",stats.line);
      perror(inpbuf);
      exit(1);
   }
   if ((opts&OPT_OUTPUT) != 0) {	/* if he wants an output */
      make_output();
   }
   read_setup();
   if (buf != NULLP) {
      struct set_key old;
      old = *(struct set_key *)buf;
      if (ioctl(stdout->_file,LDSETBF,buf) < 0) {
	 perror("error setting key buf in cled\n\t");
	 ioctl_error(&old);
	 exit(1);
      }
   }
}   

@//E*O*F cledsetup.c//
chmod u=rw,g=r,o=r cledsetup.c
 
echo x - cleddump.c
sed 's/^@//' > "cleddump.c" <<'@//E*O*F cleddump.c//'
#include <sys/types.h>
#include <sys/tty.h>
#if defined(M_UNIX)
#include <sys/termio.h>
#endif
#include <stdio.h>
#include <fcntl.h>

#include "cled_structs.h"

FILE *ofp;
int clp;

struct cle_stats stats;

main(argc,argv)
int argc;
char *argv[];
{
   int cnt;
   char *mem,*ttys;
   struct led_buf *lb,*lbtop;
   struct tty_buf *tbp,*tbtop;
   struct cle_buf *cb;

   if (argc < 2) {
      fprintf(stderr,"Useage: dumpcled output_file\n");
      exit(1);
   }
   clp = open("/dev/cled",O_RDWR);
   if (clp < 0) {
      perror("Unable to open /dev/cled");
      exit(1);
   }
   ofp = fopen(argv[1],"w");
   if (ofp == 0) {
      perror("Unable to open output file");
      exit(1);
   }
   if (ioctl(clp,LDGETS,&stats) < 0) {
      perror("Error doing LDGETS ioctl");
      exit(1);
   }
   fprintf(ofp,"Max ledbufs = %d, Max ttybufs = %d, ledbufs used = %d\n",
   	stats.ledbufs,stats.ttybufs,stats.ledbufs_used);
   fprintf(ofp,"ttybufs used = %d, Line number = %d\n\n",
   	stats.ttybufs_used,stats.line);
   mem = (char *)malloc(sizeof(struct cle_buf)+
   		stats.ledbufs*sizeof(struct led_buf)+
   		stats.ttybufs*sizeof(struct tty_buf));
   ttys = (char *)malloc(sizeof(struct tty));
   if (ioctl(clp,LDGETB,mem) < 0) {
      perror("Error doing LDGETB");
      exit(1);
   }
   cb = (struct cle_buf *)mem;   
   lbtop = lb = (struct led_buf *)(cb+1);
   tbtop = tbp = (struct tty_buf *)(lb+stats.ledbufs);
   fprintf(ofp,"lbsize = %d, lbbase = %08X, lbfree = %08X\n",
   	cb->lbsize,cb->lbbase,cb->lbfree);
   fprintf(ofp,"tbsize = %d, tbbase = %08X, tbfree = %08X, tbused = %08X\n",
   	cb->tbsize,cb->tbbase,cb->tbfree,cb->tbused);
   fprintf(ofp,"   local lbfree = %08X(%2d), tbfree = %08X(%2d), tbused = %08X(%2d)\n",
   	cb->lbfree ? lbtop+(cb->lbfree-cb->lbbase):0,cb->lbfree?cb->lbfree-cb->lbbase:0,
   	cb->tbfree ? tbtop+(cb->tbfree-cb->tbbase):0,cb->tbfree?cb->tbfree-cb->tbbase:0,
   	cb->tbused ? tbtop+(cb->tbused-cb->tbbase):0,cb->tbused?cb->tbused-cb->tbbase:0);
   for (cnt=0;cnt < stats.ttybufs;++cnt,++tbp) {
      fprintf(ofp,"\n**************** tty_buf %2d (%X) ***************\n",
      		cnt,tbp);   
      tbp->next = tbtop + (tbp->next-cb->tbbase);
      tbp->last = tbtop + (tbp->last-cb->tbbase);
      tbp->lbtop = tbp->lbtop?(lbtop + (tbp->lbtop-cb->lbbase)):0;
      fprintf(ofp,"Next - %08X(%2d), Last - %08X(%2d), lbtop - %08X(%2d)\n",
      		tbp->next,tbp->next-tbtop,
   		tbp->last,tbp->last-tbtop,
   		tbp->lbtop,tbp->lbtop?tbp->lbtop-lbtop:0);
      fprintf(ofp,"BC.c_cc - %d, flags = %02X, tty - %08X\n",
      		tbp->broadcast.c_cc,tbp->flags,tbp->ttyp);
      fprintf(ofp,"refresh = %d, sleep_r = %d, tmpsize = %d\n",
      		tbp->f_refresh,tbp->f_sleep_read,tbp->tmpsize);
      fputs("*****************************************************\n",ofp);
      if (tbp->ttyp != 0) {
	 struct tty *ttyp;
	 *(struct tty **)ttys = tbp->ttyp;
	 ttyp = (struct tty *)ttys;
	 if (ioctl(clp,LDGETTTY,ttyp) < 0) {
	    perror("Error getting tty struct");
	 } else {
	    fputs("===================================================\n",ofp);
	    fprintf(ofp,"rawq.c_cc = %d, canq.c_cc = %d, outq.c_cc = %d\n",
	    		ttyp->t_rawq.c_cc,ttyp->t_canq.c_cc,ttyp->t_outq.c_cc);
	    fprintf(ofp,"iflag = %04X, oflag = %04X, cflag = %04X, lflag = %04X\n",
	    		ttyp->t_iflag,ttyp->t_oflag,ttyp->t_cflag,ttyp->t_lflag);
	    fprintf(ofp,"state = %04X, pgrp = %d, line = %d, dstat = %04X\n",
	    		ttyp->t_state,ttyp->t_pgrp,ttyp->t_line,ttyp->t_dstat);
#if defined(M_UNIX)
            fprintf(ofp,"xstate = %02X, merr = %02X, xmp = %08X\n",
	    		ttyp->t_xstate,ttyp->t_merr,ttyp->t_xmp);
#else
            fprintf(ofp,"xstate = %02X, xxx = %02X, merr = %02X, xmp = %08X\n",
	    		ttyp->t_xstate,ttyp->t_xxx,ttyp->t_merr,ttyp->t_xmp);
#endif
	    fprintf(ofp,"delct = %d\n",ttyp->t_delct);
	    fputs("===================================================\n",ofp);
	 }
      }	    
   }
   for (cnt=0;cnt < stats.ledbufs;++cnt,++lb) {
      int comsiz,his,hsiz;
      fprintf(ofp,"\n**************** led_buf %2d (%X) ***************\n",
      		cnt,lb);   
#if MULTI_LB
      lb->next = lbtop + (lb->next-cb->lbbase);
      lb->last = lbtop + (lb->last-cb->lbbase);
#endif
      lb->ttybf = lb->ttybf ? tbtop + (lb->ttybf-cb->tbbase) : 0;

      fprintf(ofp,"Next - %08X(%2d), Last - %08X(%2d), ttybf - %08X(%2d)\n",
#if MULTI_LB
      		lb->next,lb->next-lbtop,
   		lb->last,lb->last-lbtop,
#else
   		0l,0l,0l,0l,
#endif
   		lb->ttybf,lb->ttybf?lb->ttybf-tbtop:0);
      fprintf(ofp,"Proc - %08X, pid = %d, ppid = %d, flags = %04X\n",
#if MULTI_LB
      		lb->proc,lb->pid,lb->ppid,lb->flags);
#else
   		0l,0,0,lb->flags);
#endif
      fprintf(ofp,"State - %04X, last char - %04X, prompt_size = %d\n",
      		lb->state,lb->c,lb->prmptsz);
      hsiz = his = comsiz = 0;
      if (lb->key != 0) {
	 unsigned char *hp,*hpend;
	 hp = lb->old+1;
	 hpend = lb->key-(unsigned char *)cb->lbbase+(unsigned char *)lbtop;
	 comsiz = hpend-lb->old;
	 while (*hp != 0 && hp < hpend) {
	    ++his;
	    hsiz += *hp;
	    hp += *hp;
	 }
	 if (hp >= hpend) fprintf(ofp,"Warning: history buffer overlaps keydefs\n");
      } 
      fprintf(ofp,"c_posn = %d, end_posn = %d, comsize = %d, his_size = %d, h_lines = %d\n",
      		lb->c_posn,lb->end_posn,comsiz,hsiz,his);
      fprintf(ofp,"amt owed = %d\n",lb->owed ? lb->lcurs-lb->owed : 0);
      fputs("*****************************************************\n",ofp);
   }
   fclose(ofp);
   close(clp);
   exit(0);
}
@//E*O*F cleddump.c//
chmod u=rw,g=r,o=r cleddump.c
 
echo x - cledac
sed 's/^@//' > "cledac" <<'@//E*O*F cledac//'
	    tcl.c_cc = 0;		/* init our dummy clist */
	    tcl.c_cf = tcl.c_cl = 0;
	    u.u_count -= len;		/* take from user's count */
	    ospl = spl6();		/* book says this has to be at spl6() */
	    putcbp(&tcl,src,len);	/* put the rest in a new clist */
	    splx(ospl);			/* interrupts ok */
	    if (bcl->c_cf == 0) {	/* if broadcast is empty */
		bcl->c_cf = tcl.c_cf;	/* move our temp to it */
	    } else {
		bcl->c_cl->c_next = tcl.c_cf;
	    }
	    bcl->c_cc += tcl.c_cc;
	    bcl->c_cl = tcl.c_cl;
	}
#if _SPTALLOC
	Sptfree(temp,oldlen+1);		/* done with temp space */
#endif
    }	       
    cle_kickit(tbp->ttyp);		/* make sure output is running */
}

/***************************************************************************
 * Write some text to the terminal. Writes to the terminal can occur at any
 * time by any suitably privledged process. An attempt is made to determine
 * what writes constitute the output of a "prompt" string. This is done by
 * capturing and remembering in the brodcast clist a copy of the data to
 * write from the last \r or \n in the message to the end of the message.
 * Data that has no \r or \n in it is appended to any existing data in the
 * clist (often processes do single char output to the terminal so its no 
 * wonder the system gets slow at times). If a led_buf has been assigned to
 * the process doing the write, then the "prompt" data is placed in the
 * led_buf instead of the broadcast clist. If a read is pending on the
 * terminal when a write is issued, only the data up to and including the
 * last \n is transmitted. The remainder is saved in the broadcast
 * clist. If data ends up being sent to the terminal, then the refresh bit
 * is set and the read process is awakened (which causes broadcast messages
 * to automatically refresh the input line).
 */
      clewrite(td)
      struct tty *td;
/* 
 * At entry:
 *	Process context: task.
 *	td - ptr to tty struct
 * At exit:
 *	Write data sent to the terminal and/or stored in the broadcast
 *	clist or led_buf (if one assigned).
 */
{
    int indx,ospl;
    struct led_buf *lb;
    struct tty_buf *tbp;
    if ((td->t_lflag&(ICANON|ECHO|ECHOE|ECHOK)) != (ICANON|ECHO|ECHOE|ECHOK)) {
        (*linesw[0].l_write)(td);	/* raw mode, do it via ld 0 */
	return;				/* and exit */
    }	
    tbp = find_ttybuf(td);		/* get assigned tty_buf */
    if (tbp != 0) {
        tbp->flags |= TB_WRITING;	/* signal we're writing */
	if ((tbp->flags&TB_READING) != 0) {	/* if we're reading */
	    breakthru(tbp);			/* do a breakthru sequence */
	} else {				/* not reading */
#if MULTI_LB
	    lb = find_ledbuf(tbp,u.u_procp);	/* get led_buf ptr */
	    if (lb != 0) {
		catch_prompt(tbp,lb);	/* perhaps catch a prompt */
	    } else {
		if (tbp->broadcast.c_cc > 0) send_brdcst(tbp,0);
	    }
#else
            lb = tbp->lbtop;
	    catch_prompt(tbp,lb);
#endif
	}
    }
    if (u.u_count > 0) {		/* if there's any user data to send */
	(*linesw[0].l_write)(td);	/* write user's data */
    } else {
        cle_kickit(td);			/* make sure output is running */
    }
    if (tbp != 0) {
        ospl = spl6();
        if (tbp->f_refresh && tbp->f_sleep_read) {
	    tbp->f_sleep_read = 0;
	    wakeup(tbp);
        }
        splx(ospl);
        tbp->flags &= ~TB_WRITING;	/* signal we're not writing */
    }
}
      
/***********************************************************************
 * Output interrupt routine. This routine does nothing at this time.
 * Control is passed to discipline 0 for output. It normally just moves
 * text from the t_outq clist to the t_obuf output que. Null chars and
 * timers may be set appropriately depending on the char being output.
 * This discipline has no interest in changing the behaviour of the output
 * routines.
 */
	int cleoutput(td)
	struct tty *td;
/*
 * At entry:
 *	td - ptr to tty struct
 *	Process context: Interrupt.
 * At exit:
 *	Characters may have been moved from t_outq to t_obuf and the output
 *	started.
 */
{
   int retv;
   retv = (*linesw[0].l_output)(td);
   return retv;
}
   
cledinit(dev)
int dev;
{
   int cnt;
   for (cnt = 0; cnt < linecnt; ++cnt) {
       if (linesw[cnt].l_open == cleopen) break;
   }
   if (cnt < linecnt) {
      our_lineno = cnt;
#if defined(M_UNIX)
      printcfg("cled",0,0,-1,-1,"v%s installed as ld %d.",
#else
      printf("%%cled version %s installed as line discipline %d.\n",
#endif
      	VERSION,cnt);
      garbage_collect((struct tty_buf *)0);
   } else {
#if defined(M_UNIX)
      cmn_err(CE_WARN,"Cled version %s is not in linesw table. Not installed",
#else
      printf("%%cled version %s not in linesw table. Not installed.\n",
#endif
      	VERSION);
   }
   return;
}

cledopen(dev)
int dev;
{
   return;
}

cledclose(dev)
int dev;
{
   return;
}

cledread(dev)
int dev;
{
   return;		/* returns EOF */
}

cledwrite(dev)
int dev;
{
   return;		/* writes are nops */
}

cledioctl(dev,cmd,arg,mode)
int dev,cmd,mode;
faddr_t arg;
{
    if (cmd == LDGETB) {	/* get the buffers */
	struct cle_buf bfs;
	bfs.lbsize = MAX_LEDBUFS*sizeof(struct led_buf); /* set the sizes */
	bfs.tbsize = MAX_TTYBUFS*sizeof(struct tty_buf);
	bfs.lbbase = cle_buffers;	/* these only mean something to debugger */
	bfs.lbfree = ldb_free;
	bfs.tbbase = cle_ttybuf;
	bfs.tbused = tty_used;
	bfs.tbfree = tty_free;
        bfs.procbase = proc;
	copyout(&bfs,arg,sizeof(struct cle_buf));
	arg += sizeof(struct cle_buf);
	copyout(cle_buffers,arg,bfs.lbsize);
	arg += bfs.lbsize;
	copyout(cle_ttybuf,arg,bfs.tbsize);
	return;
    }
    if (cmd == LDGETS) {
	int cnt;
	char *s;
	struct led_buf *lb;
	struct tty_buf *tbp;
	struct cle_stats sts;
	sts.ledbufs = MAX_LEDBUFS;
	sts.ttybufs = MAX_TTYBUFS;
   	sts.histsize = HISTBUFSIZ;
   	sts.promptsize = PROMPTBFSIZ;
	sts.multi_lb = MULTI_LB;
	sts.spt = _SPTALLOC;
	sts.combufsiz = COMBUFSIZ;
#if _SPTALLOC
	sts.ansisize = 256;
#else
	sts.ansisize = ANSISIZE;
#endif
	s = VERSION;
	for (cnt = 0;cnt < 4;++cnt) {
	   if ((sts.vers[cnt] = *s++) == 0) break;
	}
	tbp = tty_free;
	cnt = 0;
	if (tbp != 0) {
	    do {
		tbp = tbp->next;
		++cnt;
	    } while (tbp != tty_free && cnt < MAX_TTYBUFS);
	}
	sts.ttybufs_used = MAX_TTYBUFS-cnt;
#if MULTI_LB
	cnt = 0;
	lb = ldb_free;
	if (lb != 0) {
	    do {
		lb = lb->next;
		++cnt;
	    } while (lb != ldb_free && cnt < MAX_LEDBUFS);
	}
#endif
	sts.ledbufs_used = MAX_LEDBUFS-cnt;
        sts.line = our_lineno;
	copyout(&sts,arg,sizeof(struct cle_stats));
	return;
    }
    if (cmd == LDGETTTY) {	/* return the contents of a tty struct */
        struct tty *ttyp;
        copyin(arg,&ttyp,sizeof(ttyp));
        copyout(ttyp,arg,sizeof(struct tty));
        return;
    }
    if (cmd == LDGETC) {	/* return the contents of a clist */
        struct clist *clp;
	struct cblock *cbp;
	int cnt;
        copyin(arg,&clp,sizeof(clp));
	if (clp->c_cc != 0) {	/* if there's something in the clist */
	   int ospl;
	   ospl = spl6();
	   cbp = clp->c_cf;
	   do {
	      unsigned char siz;
	      siz = cbp->c_last-cbp->c_first;
	      if (siz != 0) {
	         copyout(&siz,arg,1);
	         ++arg;
		 copyout(&cbp->c_data[cbp->c_first],arg,siz);
	         arg += siz;
	      }	      
	      cbp = cbp->c_next;
	   } while (cbp != 0);
	   splx(ospl);
	}
	cnt =0;
	copyout(&cnt,arg,1);	   
        return;
    }
    u.u_error = ERR_BADIOCTL;
}

#endif			/* ifdef M_KERNEL */
   
#ifndef M_KERNEL
static unsigned char cmd_line[256];
static struct tty dum_tty;
  
struct  termio ostate;                 /* saved tty state */
struct  termio nstate;                 /* values for editor mode */
   
main()
{
   int c;
   dum_tty.t_cc[VINTR] = 'C'&0x1f;
   dum_tty.t_cc[VQUIT] = 'Y'&0x1f;
   dum_tty.t_cc[VERASE] = 0x7f;
   dum_tty.t_cc[VKILL] = 'U'&0x1f;
   dum_tty.t_cc[VEOF] = 'Z'&0x1f;
   dum_tty.t_cc[VEOL] = 'M'&0x1f;
   ioctl(0, TCGETA, &ostate);	/* save old state */
   ioctl(0, TCGETA, &nstate);	/* get base of new state */
   nstate.c_iflag= 0;		/* set raw input mode */
   nstate.c_oflag= 0;		/* set raw output mode */
   nstate.c_lflag= 0;		/* set raw line discp mode */
   nstate.c_cc[VEOF]= 1;	/* set eof char */
   nstate.c_cc[VEOL]= 0;	/* no specific EOL char */
   ioctl(0, TCSETA, &nstate);   /* set new mode */
   u.u_base = cmd_line;
   u.u_count = sizeof(cmd_line);
   garbage_collect((struct tty_buf *)0);
   tty_used = cle_ttybuf;
   get_ttybuf(&dum_tty);
   cle_puts("Outputting controls\r\n",&dum_tty);
   cle_puts(cle_ttybuf[0].ansi[ANSI_SETUP],&dum_tty);
   while(1) {
      if (cleread(&dum_tty) == 0) break;
      if (strlen(cmd_line) == 0) break;
      fprintf(stderr,"\r\nRecieved %d chars\r\n",strlen(cmd_line));
   }
   ioctl(0, TCSETA, &ostate);	/* reset terminal mode */
   return;
}
#endif

@//E*O*F cledac//
chmod u=rw,g=r,o=r cledac
 
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 <<\!!!
    254    876   6298 cledinst
    223    709   5060 cledinst.unix
     26     72    544 makefile
     26     72    551 makefile.unix
    753   2668  21074 cledsetup.c
    155    525   5487 cleddump.c
    311   1239   8700 cledac
   1748   6161  47714 total
!!!
wc  cledinst cledinst.unix makefile makefile.unix cledsetup.c cleddump.c cledac | 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