shepperd@dms.UUCP (Dave Shepperd) (11/10/89)
# 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@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.