From a570deaba1b1b24d2bca4fd910daaf412ac6ff21 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Wed, 10 Jan 1979 15:02:36 -0500 Subject: [PATCH] Research V7 development Work on file usr/src/cmd/sync.c Work on file usr/src/cmd/sum.c Work on file usr/src/cmd/tabs.c Work on file usr/src/cmd/standalone/conf.c Work on file usr/src/cmd/standalone/prf.c Work on file usr/src/cmd/standalone/srt0.s Work on file usr/src/cmd/standalone/mtboot.s Work on file usr/src/cmd/standalone/maketape.c Work on file usr/src/cmd/standalone/cc+ld-stand Work on file usr/src/cmd/standalone/saio.h Work on file usr/src/cmd/standalone/boot.c Work on file usr/src/cmd/standalone/cat.c Work on file usr/src/cmd/tc.c Work on file usr/src/cmd/tee.c Work on file usr/src/cmd/test.c Work on file usr/src/cmd/tk.c Work on file usr/src/cmd/time.c Co-Authored-By: Dennis Ritchie Synthesized-from: v7 --- usr/src/cmd/standalone/boot.c | 83 ++++ usr/src/cmd/standalone/cat.c | 15 + usr/src/cmd/standalone/cc+ld-stand | 3 + usr/src/cmd/standalone/conf.c | 46 +++ usr/src/cmd/standalone/maketape.c | 60 +++ usr/src/cmd/standalone/mtboot.s | 195 +++++++++ usr/src/cmd/standalone/prf.c | 169 ++++++++ usr/src/cmd/standalone/saio.h | 65 +++ usr/src/cmd/standalone/srt0.s | 76 ++++ usr/src/cmd/sum.c | 48 +++ usr/src/cmd/sync.c | 5 + usr/src/cmd/tabs.c | 194 +++++++++ usr/src/cmd/tc.c | 636 +++++++++++++++++++++++++++++ usr/src/cmd/tee.c | 95 +++++ usr/src/cmd/test.c | 189 +++++++++ usr/src/cmd/time.c | 78 ++++ usr/src/cmd/tk.c | 248 +++++++++++ 17 files changed, 2205 insertions(+) create mode 100644 usr/src/cmd/standalone/boot.c create mode 100644 usr/src/cmd/standalone/cat.c create mode 100755 usr/src/cmd/standalone/cc+ld-stand create mode 100644 usr/src/cmd/standalone/conf.c create mode 100644 usr/src/cmd/standalone/maketape.c create mode 100644 usr/src/cmd/standalone/mtboot.s create mode 100644 usr/src/cmd/standalone/prf.c create mode 100644 usr/src/cmd/standalone/saio.h create mode 100644 usr/src/cmd/standalone/srt0.s create mode 100644 usr/src/cmd/sum.c create mode 100644 usr/src/cmd/sync.c create mode 100644 usr/src/cmd/tabs.c create mode 100644 usr/src/cmd/tc.c create mode 100644 usr/src/cmd/tee.c create mode 100644 usr/src/cmd/test.c create mode 100644 usr/src/cmd/time.c create mode 100644 usr/src/cmd/tk.c diff --git a/usr/src/cmd/standalone/boot.c b/usr/src/cmd/standalone/boot.c new file mode 100644 index 0000000000..18465d07c6 --- /dev/null +++ b/usr/src/cmd/standalone/boot.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include + + +char line[100]; + +main() +{ +int i; + segflag = 2; + + + printf("Boot\n"); + do { + printf(": "); gets(line); + i = open(line,0); + } while (i < 0); + + + copyunix(i); + +} + + +copyunix(io) +register io; +{ +register addr,s; +long phys; +unsigned txtsiz,datsiz,bsssiz; +int magic; + + + lseek(io, (off_t)0, 0); + magic = getw(io); + txtsiz = getw(io); + datsiz = getw(io); + bsssiz = getw(io); + + + switch (magic) { + case 0411: + setseg(0); + lseek(io, (long)(020+txtsiz), 0); + + for(addr=0; addr!=datsiz; addr+=2) { + mtpi(getw(io),addr); + } + + clrseg(addr,bsssiz); + + phys = (long)datsiz + (long)bsssiz + 63L; + phys =/ 64; + setseg((int)phys); + + lseek(io, 020L, 0); + + for(addr=0; addr!=txtsiz; addr+=2) { + mtpi(getw(io),addr); + } + return; + case 0407: + setseg(0); + /* + * space over the header. We do this instead of seeking + * because the input might be a tape which doesn't know + * how to seek. + */ + getw(io); getw(io); getw(io); getw(io); + phys = txtsiz+datsiz; + for (addr = 0; addr != phys; addr += 2) + mtpi(getw(io),addr); + clrseg(addr, bsssiz); + return; + default: + printf("Can't load %o files\n", magic); + exit(1); + } +} diff --git a/usr/src/cmd/standalone/cat.c b/usr/src/cmd/standalone/cat.c new file mode 100644 index 0000000000..cf69e62164 --- /dev/null +++ b/usr/src/cmd/standalone/cat.c @@ -0,0 +1,15 @@ +main() +{ + int c, i; + char buf[50]; + + do { + printf("File: "); + gets(buf); + i = open(buf, 0); + } while (i <= 0); + + while ((c = getc(i)) > 0) + putchar(c); + exit(0); +} diff --git a/usr/src/cmd/standalone/cc+ld-stand b/usr/src/cmd/standalone/cc+ld-stand new file mode 100755 index 0000000000..2e71701c01 --- /dev/null +++ b/usr/src/cmd/standalone/cc+ld-stand @@ -0,0 +1,3 @@ +cc -c -O -DSTANDALONE ../$1.c +ld -s -o $1 srt0.o $1.o -lsa -lc +rm $1.o diff --git a/usr/src/cmd/standalone/conf.c b/usr/src/cmd/standalone/conf.c new file mode 100644 index 0000000000..1d180dc218 --- /dev/null +++ b/usr/src/cmd/standalone/conf.c @@ -0,0 +1,46 @@ +#include +#include +#include "saio.h" + +devread(io) +register struct iob *io; +{ + + return( (*devsw[io->i_ino.i_dev].dv_strategy)(io,READ) ); +} + +devwrite(io) +register struct iob *io; +{ + return( (*devsw[io->i_ino.i_dev].dv_strategy)(io, WRITE) ); +} + +devopen(io) +register struct iob *io; +{ + (*devsw[io->i_ino.i_dev].dv_open)(io); +} + +devclose(io) +register struct iob *io; +{ + (*devsw[io->i_ino.i_dev].dv_close)(io); +} + +nullsys() +{ ; } + +int rpstrategy(); +int rkstrategy(); +int nullsys(); +int tmstrategy(), tmrew(), tmopen(); +int htstrategy(), htopen(),htclose(); +int hpstrategy(); +struct devsw devsw[] { + "rp", rpstrategy, nullsys, nullsys, + "hp", hpstrategy, nullsys, nullsys, + "rk", rkstrategy, nullsys, nullsys, + "tm", tmstrategy, tmopen, tmrew, + "ht", htstrategy, htopen, htclose, + 0,0,0,0 +}; diff --git a/usr/src/cmd/standalone/maketape.c b/usr/src/cmd/standalone/maketape.c new file mode 100644 index 0000000000..3edcb19dda --- /dev/null +++ b/usr/src/cmd/standalone/maketape.c @@ -0,0 +1,60 @@ +#include +#define MAXB 30 +int mt; +int fd; +char buf[MAXB*512]; +char name[50]; +int blksz; + +main(argc, argv) +int argc; +char *argv[]; +{ + int i, j, k; + FILE *mf; + + if (argc != 3) { + fprintf(stderr, "Usage: maketape tapedrive makefile\n"); + exit(0); + } + if ((mt = creat(argv[1], 0666)) < 0) { + perror(argv[1]); + exit(1); + } + if ((mf = fopen(argv[2], "r")) == NULL) { + perror(argv[2]); + exit(2); + } + + j = 0; + k = 0; + for (;;) { + if ((i = fscanf(mf, "%s %d", name, &blksz))== EOF) + exit(0); + if (i != 2) { + fprintf(stderr, "Help! Scanf didn't read 2 things (%d)\n", i); + exit(1); + } + if (blksz <= 0 || blksz > MAXB) { + fprintf(stderr, "Block size %d is invalid\n", blksz); + continue; + } + if (strcmp(name, "*") == 0) { + close(mt); + mt = open(argv[1], 2); + j = 0; + k++; + continue; + } + fd = open(name, 0); + if (fd < 0) { + perror(name); + continue; + } + printf("%s: block %d, file %d\n", name, j, k); + while (read(fd, buf, 512*blksz) > 0) { + j++; + write(mt, buf, 512*blksz); + } + } +} diff --git a/usr/src/cmd/standalone/mtboot.s b/usr/src/cmd/standalone/mtboot.s new file mode 100644 index 0000000000..73ba563b8e --- /dev/null +++ b/usr/src/cmd/standalone/mtboot.s @@ -0,0 +1,195 @@ +/ tape boot program to load and transfer +/ the next item on the tape. + +/ entry is made by jsr pc,*$0 +/ so return can be rts pc + +core = 24. +halt=0 +.. = [core*2048.]-512. +start: + mov $..,sp + mov sp,r1 + cmp pc,r1 + bhis 2f + clr r0 + cmp (r0),$407 + bne 1f + mov $20,r0 +1: + mov (r0)+,(r1)+ + cmp r1,$core*2048. + blo 1b + jmp (sp) + +2: + mov $1f,*$4 + mov $340,*$6 + tst *$htcs1 + mov $htrew,rew + mov $htread,tread + br 2f +1: + mov $tmread,tread + mov $tmrew,rew +2: + jsr pc,*rew + mov $2,tapa + mov $-256.,wc + jsr pc,*tread + + mov *$2,r0 + add *$4,r0 + sub $512.,r0 + asr r0 + neg r0 + bge 1f + + mov r0,wc + mov $3,tapa + mov $512.,ba + jsr pc,*tread +1: + jsr pc,*rew + clr r0 + mov $20,r1 + mov sp,r4 + clc + ror r4 +1: + mov (r1)+,(r0)+ + sob r4,1b + jsr pc,*$0 + br . + +htcs1 = 172440 +htba = 172444 +htfc = 172446 +htcs2 = 172450 +htds = 172452 +httc = 172472 + +P800 = 1300 +P1600 = 2300 +PIP = 20000 +RESET = 40 +MOL = 10000 +ERR = 40000 +REV = 33 +READ = 71 +REW = 7 + +htread: +1: + mov ba,mtma + cmp mtapa,tapa + beq 1f + bhi 2f + jsr pc,hrrec + br 1b +2: + jsr pc,htrew + br 1b +1: + mov wc,r1 +1: + jsr pc,hrrec + add $256.,r1 + bmi 1b + rts pc + +hrrec: + mov $htds,r0 + tstb (r0) + bpl hrrec + bit $PIP,(r0) + bne hrrec + bit $MOL,(r0) + beq hrrec + mov $htfc,r0 + mov $-512.,(r0) + mov mtma,-(r0) + mov $-256.,-(r0) + mov $READ,-(r0) +1: + tstb (r0) + bpl 1b + bit $ERR,(r0) + bpl 1f + mov $RESET,*$htcs2 + mov $-1,*$htfc + mov $REV,(r0) + br hrrec +1: + add $512.,mtma + inc mtapa + rts pc + +htrew: + mov $RESET,*$htcs2 + mov $P800,*$httc + mov $REW,*$htcs1 + clr mtapa + rts pc + + +mts = 172520 +mtc = 172522 +mtbrc = 172524 +mtcma = 172526 + +tmread: +1: + mov ba,mtma + cmp mtapa,tapa + beq 1f + bhi 2f + jsr pc,tmrrec + br 1b +2: + jsr pc,tmrew + br 1b +1: + mov wc,r1 +1: + jsr pc,tmrrec + add $256.,r1 + bmi 1b + rts pc + +tmrrec: + mov $mts,r0 + bit $2,(r0)+ / rewind status + bne tmrrec + tstb (r0)+ / cu ready + bpl tmrrec + inc r0 + mov $-512.,(r0)+ / byte count + mov mtma,(r0) / bus address + mov $mtc,r0 + mov $60003,(r0) / read 800bpi +1: + tstb (r0) + bpl 1b + tst (r0)+ + bpl 1f + mov $-1,(r0) + mov $60013,-(r0) / backspace + br tmrrec +1: + add $512.,mtma + inc mtapa + rts pc + +tmrew: + mov $60017,*$mtc + clr mtapa + rts pc + +mtapa: 0 +mtma: 0 +tapa: 0 +wc: 0 +ba: 0 +rew: 0 +tread: 0 diff --git a/usr/src/cmd/standalone/prf.c b/usr/src/cmd/standalone/prf.c new file mode 100644 index 0000000000..ab6ce27969 --- /dev/null +++ b/usr/src/cmd/standalone/prf.c @@ -0,0 +1,169 @@ + +/* + * Scaled down version of C Library printf. + * Only %s %u %d (==%u) %o %x %D are recognized. + * Used to print diagnostic information + * directly on console tty. + * Since it is not interrupt driven, + * all system activities are pretty much + * suspended. + * Printf should not be used for chit-chat. + */ +printf(fmt, x1) +register char *fmt; +unsigned x1; +{ + register c; + register unsigned int *adx; + char *s; + + adx = &x1; +loop: + while((c = *fmt++) != '%') { + if(c == '\0') + return; + putchar(c); + } + c = *fmt++; + if(c == 'd' || c == 'u' || c == 'o' || c == 'x') + printn((long)*adx, c=='o'? 8: (c=='x'? 16:10)); + else if(c == 's') { + s = (char *)*adx; + while(c = *s++) + putchar(c); + } else if (c == 'D') { + printn(*(long *)adx, 10); + adx += (sizeof(long) / sizeof(int)) - 1; + } else if (c == 'c') + putchar((char *)*adx); + adx++; + goto loop; +} + +/* + * Print an unsigned integer in base b. + */ +printn(n, b) +long n; +{ + register long a; + + if (n<0) { /* shouldn't happen */ + putchar('-'); + n = -n; + } + if(a = n/b) + printn(a, b); + putchar("0123456789ABCDEF"[(int)(n%b)]); +} + + + +struct device { + int rcsr,rbuf; + int tcsr,tbuf; +}; +struct device *KLADDR {0177560}; +putchar(c) +register c; +{ + register s; + register unsigned timo; + + /* + * If last char was a break or null, don't print + if ((KLADDR->rbuf&0177) == 0) + return; + */ + timo = 60000; + /* + * Try waiting for the console tty to come ready, + * otherwise give up after a reasonable time. + */ + while((KLADDR->tcsr&0200) == 0) + if(--timo == 0) + break; + if(c == 0) + return; + s = KLADDR->tcsr; + KLADDR->tcsr = 0; + KLADDR->tbuf = c; + if(c == '\n') { + putchar('\r'); + putchar(0177); + putchar(0177); + } + putchar(0); + KLADDR->tcsr = s; +} + +getchar() +{ + register c; + + KLADDR->rcsr = 1; + while((KLADDR->rcsr&0200)==0); + c = KLADDR->rbuf&0177; + if (c=='\r') + c = '\n'; + putchar(c); + return(c); +} + +gets(buf) +char *buf; +{ +register char *lp; +register c; + + lp = buf; + for (;;) { + c = getchar() & 0177; + if (c>='A' && c<='Z') + c -= 'A' - 'a'; + if (lp != buf && *(lp-1) == '\\') { + lp--; + if (c>='a' && c<='z') { + c += 'A' - 'a'; + goto store; + } + switch ( c) { + case '(': + c = '{'; + break; + case ')': + c = '}'; + break; + case '!': + c = '|'; + break; + case '^': + c = '~'; + break; + case '\'': + c = '`'; + break; + } + } + store: + switch(c) { + case '\n': + case '\r': + c = '\n'; + *lp++ = '\0'; + return; + case '\b': + case '#': + lp--; + if (lp < buf) + lp = buf; + continue; + case '@': + lp = buf; + putchar('\n'); + continue; + default: + *lp++ = c; + } + } +} diff --git a/usr/src/cmd/standalone/saio.h b/usr/src/cmd/standalone/saio.h new file mode 100644 index 0000000000..fc074fc967 --- /dev/null +++ b/usr/src/cmd/standalone/saio.h @@ -0,0 +1,65 @@ +/* + * header file for standalone package + */ + +/* + * io block: includes an + * inode, cells for the use of seek, etc, + * and a buffer. + */ +struct iob { + char i_flgs; + struct inode i_ino; + int i_unit; + daddr_t i_boff; + daddr_t i_cyloff; + off_t i_offset; + daddr_t i_bn; + char *i_ma; + int i_cc; + char i_buf[512]; +}; + +#define F_READ 01 +#define F_WRITE 02 +#define F_ALLOC 04 +#define F_FILE 010 + + + + +/* + * dev switch + */ +struct devsw { + char *dv_name; + int (*dv_strategy)(); + int (*dv_open)(); + int (*dv_close)(); +}; + +struct devsw devsw[]; + +/* + * request codes. Must be the same a F_XXX above + */ +#define READ 1 +#define WRITE 2 + + +#define NBUFS 4 + + +char b[NBUFS][512]; +daddr_t blknos[NBUFS]; + + + +#define NFILES 4 +struct iob iob[NFILES]; + +/* + * Set to which 32Kw segment the code is physically running in. + * Must be set by the users main (or there abouts). + */ +int segflag; diff --git a/usr/src/cmd/standalone/srt0.s b/usr/src/cmd/standalone/srt0.s new file mode 100644 index 0000000000..bb4727acfd --- /dev/null +++ b/usr/src/cmd/standalone/srt0.s @@ -0,0 +1,76 @@ +/ Startup code for two-stage bootstrap + +/ non-UNIX instructions +mfpi = 6500^tst +stst = 170300^tst +mtpi = 6600^tst +mfpd = 106500^tst +mtpd = 106600^tst +spl = 230 +ldfps = 170100^tst +stfps = 170200^tst +wait = 1 +rtt = 6 +reset = 5 +/ trap = 104400 + +PS = 177776 + +.globl _end +.globl _main, __rtt +.globl _edata + jmp start + +/ +/ trap vectors +/ + trap;340 + trap;341 / illegal instruction + trap;342 / BPT + trap;343 / IOT + trap;344 / POWER FAIL + trap;345 / EMT +tvec: + start;346 / TRAP +.=400^. +.text + + +start: + mov $340,*$PS + mov $trap,tvec +/ fix up stack segment clobbered by trap + mov $1400,*$KDSA6 + mov $157776,sp + mov $_edata,r0 + mov $_end,r1 + sub r0,r1 + inc r1 + clc + ror r1 +1: + clr (r0)+ + sob r1,1b + jsr pc,_main + +/ fix up stack to point at trap ps-pc pair +/ so we can return to the bootstrap +__rtt: + clr *$KDSA6 + mov $140000,sp + rtt / we hope! + br . + + +.globl _trap +trap: + mov r0,-(sp) + mov r1,-(sp) + mov *$PS,-(sp) + jsr pc,_trap + tst (sp)+ + mov (sp)+,r1 + mov (sp)+,r0 + rtt + +KDSA6 = 172374 diff --git a/usr/src/cmd/sum.c b/usr/src/cmd/sum.c new file mode 100644 index 0000000000..64acab1ccd --- /dev/null +++ b/usr/src/cmd/sum.c @@ -0,0 +1,48 @@ +/* + * Sum bytes in file mod 2^16 + */ + +#include + +main(argc,argv) +char **argv; +{ + register unsigned sum; + register i, c; + register FILE *f; + register long nbytes; + int errflg = 0; + + i = 1; + do { + if(i < argc) { + if ((f = fopen(argv[i], "r")) == NULL) { + fprintf(stderr, "sum: Can't open %s\n", argv[i]); + errflg += 10; + continue; + } + } else + f = stdin; + sum = 0; + nbytes = 0; + while ((c = getc(f)) != EOF) { + nbytes++; + if (sum&01) + sum = (sum>>1) + 0x8000; + else + sum >>= 1; + sum += c; + sum &= 0xFFFF; + } + if (ferror(f)) { + errflg++; + fprintf(stderr, "sum: read error on %s\n", argc>1?argv[i]:"-"); + } + printf("%05u%6ld", sum, (nbytes+BUFSIZ-1)/BUFSIZ); + if(argc > 2) + printf(" %s", argv[i]); + printf("\n"); + fclose(f); + } while(++i < argc); + exit(errflg); +} diff --git a/usr/src/cmd/sync.c b/usr/src/cmd/sync.c new file mode 100644 index 0000000000..3afb9b8256 --- /dev/null +++ b/usr/src/cmd/sync.c @@ -0,0 +1,5 @@ +main() +{ + + sync(); +} diff --git a/usr/src/cmd/tabs.c b/usr/src/cmd/tabs.c new file mode 100644 index 0000000000..19ed33135f --- /dev/null +++ b/usr/src/cmd/tabs.c @@ -0,0 +1,194 @@ +#include +#include + +#define SP ' ' +#define TB '\t' +#define NL '\n' + +# define ESC 033 +# define RHM 060 +# define SI 017 +# define DEL 0177 +# define SET '1' +# define CLR '2' +# define MGN '9' +# define CR '\r' +# define BS '\b' + +struct sysnod { + char *sysnam; + int sysval; +}; + +#define DASI300 1 +#define DASI300S 2 +#define DASI450 3 +#define TN300 4 +#define TTY37 5 +#define HP 6 +struct sysnod tty[] = { + {"dasi300", DASI300}, + {"300", DASI300}, + {"dasi300s", DASI300S}, + {"300s", DASI300S}, + {"dasi450", DASI450}, + {"450", DASI450}, + {"37", TTY37}, + {"tty37", TTY37}, + {"tn300", TN300}, + {"terminet", TN300}, + {"tn", TN300}, + {"hp", HP}, + {0, 0}, +}; +int margset = 1; + +syslook(w) +char *w; +{ + register struct sysnod *sp; + + for (sp = tty; sp->sysnam!=NULL; sp++) + if (strcmp(sp->sysnam, w)==0) + return(sp->sysval); + return(0); +} + +main(argc,argv) +int argc; char **argv; +{ + struct sgttyb tb; + int type; + + type=0; + if (argc>=2 && strcmp(argv[1],"-n")==0) { + margset--; argc--; argv++; + } + if (argc>=2) { + type=syslook(argv[1]); + } + + switch(type) { + + case DASI300: dasi300(); break; + + case DASI300S: dasi300(); break; + + case DASI450: dasi450(); break; + + case TN300: tn300(); break; + + case TTY37: tty37(); break; + + case HP: hp2645(); break; + + default: + gtty (0, &tb); + if ( (tb.sg_flags & (LCASE|CRMOD)) == CRMOD) { + /* test for CR map on, upper case off, i.e. terminet but not 33 */ + if ((tb.sg_ispeed) == B300) /* test for 300 baud */ + misc(); + } + else if ((tb.sg_flags & (CRMOD|LCASE)) == 0 && (tb.sg_ispeed ) == B150) { + /* apparent model 37 */ + tty37(); + } + } +} + +clear(n) +{ + escape(CLR); + delay(n); + putchar(CR); nl(); +} + +delay(n) +{ + while (n--) putchar(DEL); +} + +tabs(n) +{ + int i,j; + + if(margset) n--; + + for( i=0; i +#include + +#define oput(c) if (pgskip==0) putchar(c); else; +#define MAXY 3071 +#define US 037 +#define GS 035 +#define ESC 033 +#define FF 014 +#define DBL 0200 + +int pl = 11*144; +int mpy = 1; +int div = 1; +char *ap; +int ch; +int nonumb; +int psize = 10; +int dfact = 1; +int esc; +int escd; +int verd; +int esct; +int osize = 02; +int size = 02; +int rx; +int xx; +int yy = MAXY+62+48; +int leadtot = -31; +int ohy = -1; +int ohx = -1; +int oxb = -1; +int oly = -1; +int olx = -1; +int tflag; +int railmag; +int lead; +int skip; +int pgskip; +int ksize = ';'; +int mcase; +int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217}; +int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18}; +int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'}; +int first = 1; +int alpha; +extern char *asctab[128]; +extern char *spectab[128]; +int erase = 1; +int (*sigint)(); +int (*sigquit)(); + +main(argc,argv) +int argc; +char **argv; +{ + register i, j; + register char *k; + extern ex(); + + while((--argc > 0) && ((++argv)[0][0]=='-')){ + switch(argv[0][1]){ + case 'p': + ap = &argv[0][2]; + dfact = 72; + if(i = atoi())pl = i/3; + continue; + case 't': + tflag++; + continue; + case 's': + ap = &argv[0][2]; + dfact = 1; + pgskip = atoi(); + continue; + default: + dfact = 1; + ap = &argv[0][1]; + if(i = atoi())mpy = i; + if(i = atoi())div = i; + continue; + } + } + if(argc){ + if (freopen(argv[0], "r", stdin) == NULL) { + fprintf(stderr, "tc: cannot open %s\n", argv[0]); + exit(1); + } + } + sigint = signal(SIGINT, ex); + sigquit = signal(SIGQUIT, SIG_IGN); + while((i = getchar()) != EOF){ + if(!i)continue; + if(i & 0200){ + esc += (~i) & 0177; + continue; + } + if(esc){ + if(escd)esc = -esc; + esct += esc; + xx += (esc*mpy + rx)/div; + rx = (esc*mpy + rx)%div; + sendpt(); + esc = 0; + } + switch(i){ + case 0100: /*init*/ + escd = verd = mcase = railmag = xx = 0; + yy = MAXY + 48; + leadtot = -31; + ohy = oxb = oly = ohx = olx = -1; + oput(US); + fflush(stdout); + if(!first && !tflag)kwait(); + if(first){ + first = 0; + yy += 62; + } + init(); + continue; + case 0101: /*lower rail*/ + railmag &= ~01; + continue; + case 0102: /*upper rail*/ + railmag |= 01; + continue; + case 0103: /*upper mag*/ + railmag |= 02; + continue; + case 0104: /*lower mag*/ + railmag &= ~02; + continue; + case 0105: /*lower case*/ + mcase = 0; + continue; + case 0106: /*upper case*/ + mcase = 0100; + continue; + case 0107: /*escape forward*/ + escd = 0; + continue; + case 0110: /*escape backward*/ + escd = 1; + continue; + case 0111: /*stop*/ + continue; + case 0112: /*lead forward*/ + verd = 0; + continue; + case 0113: /*undefined*/ + continue; + case 0114: /*lead backward*/ + verd = 1; + continue; + case 0115: /*undefined*/ + case 0116: + case 0117: + continue; + } + if((i & 0340) == 0140){ /*leading*/ + lead = (~i) & 037; + if(verd)lead = -lead; + if((leadtot += lead) > pl){ + leadtot = lead; + oput(US); + fflush(stdout); + if(!tflag)kwait(); + yy = MAXY; + if(pgskip)--pgskip; + init(); + continue; + } + if(skip)continue; + if((yy -= (lead<<1)) < 0){ + skip++; + yy = 0; + }else sendpt(); + continue; + } + if((i & 0360) == 0120){ /*size change*/ + i &= 017; + for(j = 0; i != (stab[j] & 017); j++); + osize = size; + size = stab[j]; + psize = rtab[j]; + ksize = ktab[j]; + oput(ESC); + oput(ksize); + i = 0; + if(!(osize & DBL) && (size & DBL))i = -55; + else if((osize & DBL) && !(size & DBL))i = 55; + if(escd)i = -i; + esc += i; + continue; + } + if(i & 0300)continue; + i = (i & 077) | mcase; + if(railmag != 03)k = asctab[i]; + else k = spectab[i]; + if(alpha)sendpt(); + if(*k!='\0'){ + oput(US); + while(*k & 0377)oput(*k++); + alpha++; + continue; + }else{ + if(railmag != 03){ + switch(i){ + case 0124: lig("fi"); break; + case 0125: lig("fl"); break; + case 0126: lig("ff"); break; + case 0130: lig("ffl"); break; + case 0131: lig("ffi"); break; + default: continue; + } + } + continue; + } + } + ex(); +} +lig(x) +char *x; +{ + register i, j; + register char *k; + + j = 0; + k = x; + oput(US); + oput(*k++); + i = psize * 8 * mpy / (div * 6); /* 8/36 em */ + while(*k){ + xx += i; + j += i; + sendpt(); + oput(US); + oput(*k++); + } + xx -= j; + sendpt(); +} +init(){ + + fflush(stdout); + if(erase){ + oput(ESC); + oput(FF); + }else erase = 1; + oput(ESC); + oput(ksize); + /*delay about a second*/ +/* let the system do it... + for(i = 960; i > 0; i--)oput(GS); +*/ + skip = 0; + sendpt(); +} +ex(){ + yy = MAXY; + xx = 0; + sendpt(); + oput(ESC); + oput(';'); + oput(US); + fflush(stdout); + exit(0); +} +kwait(){ + char buf[128]; char *bptr; char c; + if(pgskip) return; +next: + bptr=buf; + while((c=readch())&&(c!='\n')) *bptr++=c; + *bptr=0; + if(bptr!=buf){ + bptr = buf; + if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;} + else switch(*bptr++){ + case 'e': + erase = 0; + goto next; + case 's': + ap = &buf[1]; + dfact = 1; + pgskip = atoi() + 1; + goto next; + default: + fputs("?\n", stderr); + goto next; + } + } + else if (c==0) ex(); + else return; +} +callunix(line) +char line[]; +{ + int rc, status, unixpid; + if( (unixpid=fork())==0 ) { + signal(SIGINT,sigint); signal(SIGQUIT,sigquit); + close(0); dup(2); + execl("/bin/sh", "-sh", "-c", line, 0); + exit(255); + } + else if(unixpid == -1) + return; + else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); + while( (rc = wait(&status)) != unixpid && rc != -1 ) ; + signal(SIGINT,ex); signal(SIGQUIT,sigquit); + } +} +readch(){ + char c; + if (read(2,&c,1)<1) c=0; + return(c); +} +sendpt(){ + int hy,xb,ly,hx,lx; + + oput(GS); + hy = ((yy>>7) & 037); + xb = ((xx & 03) + ((yy<<2) & 014) & 017); + ly = ((yy>>2) & 037); + hx = ((xx>>7) & 037); + lx = ((xx>>2) & 037); + if(hy != ohy)oput(hy | 040); + if(xb != oxb)oput(xb | 0140); + if((ly != oly) || (hx != ohx) || (xb != oxb)) + oput(ly | 0140); + if(hx != ohx)oput(hx | 040); + oput(lx | 0100); + ohy = hy; + oxb = xb; + oly = ly; + ohx = hx; + olx = lx; + alpha = 0; + return; +} +atoi() +{ + register i, j, acc; + int field, digits; + long dd; + long tscale(); + + field = digits = acc = 0; +a1: + while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){ + field++; + digits++; + acc = 10*acc + j; + } + if(i == '.'){ + field++; + digits = 0; + goto a1; + } + if(!(ch = i))ch = 'x'; + dd = tscale(acc); + acc = dd; + if((field != digits) && (digits > 0)){ + j = 1; + while(digits--)j *= 10; + acc = dd/j; + } + nonumb = !field; + ch = 0; + return(acc); +} +long tscale(n) +int n; +{ + register i, j; + + switch(i = getch()){ + case 'u': + j = 1; + break; + case 'p': /*Points*/ + j = 6; + break; + case 'i': /*Inches*/ + j = 432; + break; + case 'c': /*Centimeters; should be 170.0787*/ + j = 170; + break; + case 'P': /*Picas*/ + j = 72; + break; + default: + j = dfact; + ch = i; + } + return((long)n*j); +} +getch(){ + register i; + + if(ch){ + i = ch; + ch = 0; + return(i); + } + return(*ap++); +} + +char *asctab[128] { +"\0", /*blank*/ +"h", /*h*/ +"t", /*t*/ +"n", /*n*/ +"m", /*m*/ +"l", /*l*/ +"i", /*i*/ +"z", /*z*/ +"s", /*s*/ +"d", /*d*/ +"b", /*b*/ +"x", /*x*/ +"f", /*f*/ +"j", /*j*/ +"u", /*u*/ +"k", /*k*/ +"\0", /*blank*/ +"p", /*p*/ +"-", /*_ 3/4 em dash*/ +";", /*;*/ +"\0", /*blank*/ +"a", /*a*/ +"_", /*rule*/ +"c", /*c*/ +"`", /*` open*/ +"e", /*e*/ +"\'", /*' close*/ +"o", /*o*/ +"\0", /*1/4*/ +"r", /*r*/ +"\0", /*1/2*/ +"v", /*v*/ +"-", /*- hyphen*/ +"w", /*w*/ +"q", /*q*/ +"/", /*/*/ +".", /*.*/ +"g", /*g*/ +"\0", /*3/4*/ +",", /*,*/ +"&", /*&*/ +"y", /*y*/ +"\0", /*blank*/ +"%", /*%*/ +"\0", /*blank*/ +"Q", /*Q*/ +"T", /*T*/ +"O", /*O*/ +"H", /*H*/ +"N", /*N*/ +"M", /*M*/ +"L", /*L*/ +"R", /*R*/ +"G", /*G*/ +"I", /*I*/ +"P", /*P*/ +"C", /*C*/ +"V", /*V*/ +"E", /*E*/ +"Z", /*Z*/ +"D", /*D*/ +"B", /*B*/ +"S", /*S*/ +"Y", /*Y*/ +"\0", /*blank*/ +"F", /*F*/ +"X", /*X*/ +"A", /*A*/ +"W", /*W*/ +"J", /*J*/ +"U", /*U*/ +"K", /*K*/ +"0", /*0*/ +"1", /*1*/ +"2", /*2*/ +"3", /*3*/ +"4", /*4*/ +"5", /*5*/ +"6", /*6*/ +"7", /*7*/ +"8", /*8*/ +"9", /*9*/ +"*", /***/ +"-", /*minus*/ +"", /*fi*/ +"", /*fl*/ +"", /*ff*/ +"\033\016Z\bM\033\017", /*cent sign*/ +"", /*ffl*/ +"", /*ffi*/ +"(", /*(*/ +")", /*)*/ +"[", /*[*/ +"]", /*]*/ +"\033\016J\033\017", /*degree*/ +"\033\016M\b_\033\017", /*dagger*/ +"=", /*=*/ +"\033\016O\b&\033\017", /*registered*/ +":", /*:*/ +"+", /*+*/ +"\0", /*blank*/ +"!", /*!*/ +"\033\016O\b~\033\017", /*bullet*/ +"?", /*?*/ +"\'", /*foot mark*/ +"|", /*|*/ +"\0", /*blank*/ +"\033\016O\b#\033\017", /*copyright*/ +"\033\016L\033\017", /*square*/ +"$" }; /*$*/ + +char *spectab[128] = { +"\0", /*blank*/ +"\033\016(\bM\033\017", /*psi*/ +"\033\016o\b_\033\017", /*theta*/ +"v\b)", /*nu*/ +"\033\016V\b,\033\017", /*mu*/ +"\033\016)\b?\033\017", /*lambda*/ +"\033\016I\033\017", /*iota*/ +"S\b\033\016Z\033\017", /*zeta*/ +"o\b\'", /*sigma*/ +"o\b\033\0165\033\017", /*delta*/ +"\033\016b\033\017", /*beta*/ +"\033\016e\bc\033\017", /*xi*/ +"j\b\033\016C\033\017", /*eta*/ +"\033\016O\bM\033\017", /*phi*/ +"\033\016(\033\017", /*upsilon*/ +"\033\016k\033\017", /*kappa*/ +"\0", /*blank*/ +"T\b\033\016S\033\017", /*pi*/ +"@", /*at-sign*/ +"\033\016U\033\017", /*down arrow*/ +"\0", /*blank*/ +"\033\016A\033\017", /*alpha*/ +"|", /*or*/ +"l\b/", /*chi*/ +"\"", /*"*/ +"\033\016E\033\017", /*epsilon*/ +"=", /*=*/ +"\033\016O\033\017", /*omicron*/ +"\033\016[\033\017", /*left arrow*/ +"\033\016R\033\017", /*rho*/ +"\033\016Y\033\017", /*up arrow*/ +"\033\016N\033\017", /*tau*/ +"_", /*underrule*/ +"\\", /*\*/ +"I\b\033\016(\033\017", /*Psi*/ +"\033\016O\bJ\033\017", /*bell system sign*/ +"\033\016W\bX\033\017", /*infinity*/ +"`\b/", /*gamma*/ +"\033\016X\bF\033\017", /*improper superset*/ +"\033\016A\033\017", /*proportional to*/ +"\033\016\\\b]\033\017", /*right hand*/ +"\033\016W\033\017", /*omega*/ +"\0", /*blank*/ +"\033\016G\033\017", /*gradient*/ +"\0", /*blank*/ +"I\033\016\bO\033\017", /*Phi*/ +"O\b=", /*Theta*/ +"O\b_", /*Omega*/ +"\033\016V\033\017", /*cup (union)*/ +"\033\016@\033\017", /*root en*/ +"s", /*terminal sigma*/ +"\033\016)\bK\033\017", /*Lambda*/ +"-", /*minus*/ +"\033\016S\bK\033\017", /*Gamma*/ +"\033\016i\033\017", /*integral sign*/ +"\033\016t\b'\033\017", /*Pi*/ +"\033\016Z\033\017", /*subset of*/ +"\033\016X\033\017", /*superset of*/ +"\033\016T\033\017", /*approximates*/ +"o\b`", /*partial derivative*/ +"\033\016H\033\017", /*Delta*/ +"\033\016I\b'\033\017", /*square root*/ +">\b\033\016F\b@\033\017", /*Sigma*/ +"\033\016T\bF\033\017", /*approx =*/ +"\0", /*blank*/ +">", /*>*/ +"\033\016_\bF\b@\033\017", /*Xi*/ +"<", /*<*/ +"/", /*slash (longer)*/ +"\033\016C\033\017", /*cap (intersection)*/ +"\033\016y\033\017", /*Upsilon*/ +"\033\016|\033\017", /*not*/ +"|", /*right ceiling (rt of ")*/ +"|", /*left top (of big curly)*/ +"|", /*bold vertical*/ +"|", /*left center of big curly bracket*/ +"|", /*left bottom*/ +"|", /*right top*/ +"|", /*right center of big curly bracket*/ +"|", /*right bot*/ +"|", /*right floor (rb of ")*/ +"|", /*left floor (left bot of big sq bract)*/ +"|", /*left ceiling (lt of ")*/ +"\033\016=\033\017", /*multiply*/ +"\033\016+\033\017", /*divide*/ +"+\b_", /*plus-minus*/ +"\033\016$\033\017", /*<=*/ +"\033\016^\033\017", /*>=*/ +"=\b_", /*identically equal*/ +"\033\016*\033\017", /*not equal*/ +"{", /*{*/ +"}", /*}*/ +"\'", /*' acute accent*/ +"`", /*` grave accent*/ +"^", /*^*/ +"#", /*sharp*/ +"\033\016|\b[\033\017", /*left hand*/ +"\033\016c\b_\033\017", /*member of*/ +"~", /*~*/ +"\033\016O\b/\033\017", /*empty set*/ +"\0", /*blank*/ +"\033\016%\bM\033\017", /*dbl dagger*/ +"|", /*box rule*/ +"*", /*asterisk*/ +"\033\016Z\bF\033\017", /*improper subset*/ +"\033\016O\033\017", /*circle*/ +"\0", /*blank*/ +"+", /*eqn plus*/ +"\033\016]\033\017", /*right arrow*/ +"g\b\033\016C\033\017" }; /*section mark*/ diff --git a/usr/src/cmd/tee.c b/usr/src/cmd/tee.c new file mode 100644 index 0000000000..6050d310bb --- /dev/null +++ b/usr/src/cmd/tee.c @@ -0,0 +1,95 @@ +/* + * tee-- pipe fitting + */ + +#include +#include +#include +#include +int openf[20] = { 1 }; +int n = 1; +int t = 0; +int aflag; + +char in[512]; + +char out[512]; + +extern errno; +long lseek(); + +main(argc,argv) +char **argv; +{ + int register r,w,p; + struct stat buf; + while(argc>1&&argv[1][0]=='-') { + switch(argv[1][1]) { + case 'a': + aflag++; + break; + case 'i': + case 0: + signal(SIGINT, SIG_IGN); + } + argv++; + argc--; + } + fstat(1,&buf); + t = (buf.st_mode&S_IFMT)==S_IFCHR; + if(lseek(1,0L,1)==-1&&errno==ESPIPE) + t++; + while(argc-->1) { + if(aflag) { + openf[n] = open(argv[1],1); + if(openf[n] < 0) + openf[n] = creat(argv[1],0666); + lseek(openf[n++],0L,2); + } else + openf[n++] = creat(argv[1],0666); + if(stat(argv[1],&buf)>=0) { + if((buf.st_mode&S_IFMT)==S_IFCHR) + t++; + } else { + puts("tee: cannot open "); + puts(argv[1]); + puts("\n"); + n--; + } + argv++; + } + r = w = 0; + for(;;) { + for(p=0;p<512;) { + if(r>=w) { + if(t>0&&p>0) break; + w = read(0,in,512); + r = 0; + if(w<=0) { + stash(p); + return; + } + } + out[p++] = in[r++]; + } + stash(p); + } +} + +stash(p) +{ + int k; + int i; + int d; + d = t ? 16 : p; + for(i=0; i +#include +#include +#define EQ(a,b) ((tmp=a)==0?0:(strcmp(tmp,b)==0)) + +#define DIR 1 +#define FIL 2 +int ap; +int ac; +char **av; +char *tmp; + +main(argc, argv) +char *argv[]; +{ + + ac = argc; av = argv; ap = 1; + if(EQ(argv[0],"[")) { + if(!EQ(argv[--ac],"]")) + synbad("] missing",""); + } + argv[ac] = 0; + if (ac<=1) exit(1); + exit(exp()?0:1); +} + +char *nxtarg(mt) { + + if (ap>=ac) { + if(mt) { + ap++; + return(0); + } + synbad("argument expected",""); + } + return(av[ap++]); +} + +exp() { + int p1; + + p1 = e1(); + if (EQ(nxtarg(1), "-o")) return(p1 | exp()); + ap--; + return(p1); +} + +e1() { + int p1; + + p1 = e2(); + if (EQ(nxtarg(1), "-a")) return (p1 & e1()); + ap--; + return(p1); +} + +e2() { + if (EQ(nxtarg(0), "!")) + return(!e3()); + ap--; + return(e3()); +} + +e3() { + int p1; + register char *a; + char *p2; + int int1, int2; + + a=nxtarg(0); + if(EQ(a, "(")) { + p1 = exp(); + if(!EQ(nxtarg(0), ")")) synbad(") expected",""); + return(p1); + } + + if(EQ(a, "-r")) + return(tio(nxtarg(0), 0)); + + if(EQ(a, "-w")) + return(tio(nxtarg(0), 1)); + + if(EQ(a, "-d")) + return(ftype(nxtarg(0))==DIR); + + if(EQ(a, "-f")) + return(ftype(nxtarg(0))==FIL); + + if(EQ(a, "-s")) + return(fsizep(nxtarg(0))); + + if(EQ(a, "-t")) + if(ap>=ac) + return(isatty(1)); + else + return(isatty(atoi(nxtarg(0)))); + + if(EQ(a, "-n")) + return(!EQ(nxtarg(0), "")); + if(EQ(a, "-z")) + return(EQ(nxtarg(0), "")); + + p2 = nxtarg(1); + if (p2==0) + return(!EQ(a,"")); + if(EQ(p2, "=")) + return(EQ(nxtarg(0), a)); + + if(EQ(p2, "!=")) + return(!EQ(nxtarg(0), a)); + + if(EQ(a, "-l")) { + int1=length(p2); + p2=nxtarg(0); + } else{ int1=atoi(a); + } + int2 = atoi(nxtarg(0)); + if(EQ(p2, "-eq")) + return(int1==int2); + if(EQ(p2, "-ne")) + return(int1!=int2); + if(EQ(p2, "-gt")) + return(int1>int2); + if(EQ(p2, "-lt")) + return(int1=int2); + if(EQ(p2, "-le")) + return(int1<=int2); + + synbad("unknown operator ",p2); +} + +tio(a, f) +char *a; +int f; +{ + + f = open(a, f); + if (f>=0) { + close(f); + return(1); + } + return(0); +} + +ftype(f) +char *f; +{ + struct stat statb; + + if(stat(f,&statb)<0) + return(0); + if((statb.st_mode&S_IFMT)==S_IFDIR) + return(DIR); + return(FIL); +} + +fsizep(f) +char *f; +{ + struct stat statb; + if(stat(f,&statb)<0) + return(0); + return(statb.st_size>0); +} + +synbad(s1,s2) +char *s1, *s2; +{ + write(2, "test: ", 6); + write(2, s1, strlen(s1)); + write(2, s2, strlen(s2)); + write(2, "\n", 1); + exit(255); +} + +length(s) + char *s; +{ + char *es=s; + while(*es++); + return(es-s-1); +} diff --git a/usr/src/cmd/time.c b/usr/src/cmd/time.c new file mode 100644 index 0000000000..5c63d666e4 --- /dev/null +++ b/usr/src/cmd/time.c @@ -0,0 +1,78 @@ +/* time command */ + +#include +#include +#include +#include + +extern int errno; +extern char *sys_errlist[]; + +main(argc, argv) +char **argv; +{ + struct tms buffer, obuffer; + int status; + register p; + time_t before, after; + + if(argc<=1) + exit(0); + time(&before); + p = fork(); + if(p == -1) { + fprintf(stderr, "Try again.\n"); + exit(1); + } + if(p == 0) { + execvp(argv[1], &argv[1]); + fprintf(stderr, "%s: %s\n", argv[1], sys_errlist[errno]); + exit(1); + } + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + times(&obuffer); + while(wait(&status) != p) + times(&obuffer); + time(&after); + if((status&0377) != 0) + fprintf(stderr,"Command terminated abnormally.\n"); + times(&buffer); + fprintf(stderr,"\n"); + printt("real", (after-before) * 60); + printt("user", buffer.tms_cutime - obuffer.tms_cutime); + printt("sys ", buffer.tms_cstime - obuffer.tms_cstime); + exit(status>>8); +} + +char quant[] = { 6, 10, 10, 6, 10, 6, 10, 10, 10 }; +char *pad = "000 "; +char *sep = "\0\0.\0:\0:\0\0"; +char *nsep = "\0\0.\0 \0 \0\0"; + +printt(s, a) +char *s; +long a; +{ + char digit[9]; + register i; + char c; + int nonzero; + + for(i=0; i<9; i++) { + digit[i] = a % quant[i]; + a /= quant[i]; + } + fprintf(stderr,s); + nonzero = 0; + while(--i>0) { + c = digit[i]!=0 ? digit[i]+'0': + nonzero ? '0': + pad[i]; + fprintf(stderr,"%c",c); + nonzero |= digit[i]; + c = nonzero?sep[i]:nsep[i]; + fprintf(stderr,"%c",c); + } + fprintf(stderr,"\n"); +} diff --git a/usr/src/cmd/tk.c b/usr/src/cmd/tk.c new file mode 100644 index 0000000000..715b6a01db --- /dev/null +++ b/usr/src/cmd/tk.c @@ -0,0 +1,248 @@ +/* + * optimize output for Tek 4014 + */ + +#include +#include + +#define MAXY 3071 +#define LINE 47 +#define XOFF 248 +#define US 037 +#define GS 035 +#define ESC 033 +#define CR 015 +#define FF 014 +#define SO 016 +#define SI 017 + +int pl = 66*LINE; +int yyll = -1; +char obuf[BUFSIZ]; +int xx = XOFF; +int xoff = XOFF; +int coff = 0; +int ncol = 0; +int maxcol = 1; +int yy = MAXY; +int ohy = -1; +int ohx = -1; +int oxb = -1; +int oly = -1; +int olx = -1; +int alpha; +int ry; +FILE *ttyin; + +main(argc, argv) +int argc; +char **argv; +{ + register i, j; + extern ex(); + + while (--argc > 0 && (++argv)[0][0]=='-') + switch(argv[0][1]) { + case 'p': + if (i = atoi(&argv[0][2])) + pl = i; + yyll = MAXY + 1 - pl; + break; + default: + if (i = atoi(&argv[0][1])) { + maxcol = i; + xx = xoff = 0; + coff = 4096/i; + } + break; + } + if ((ttyin = fopen("/dev/tty", "r")) != NULL) + setbuf(ttyin, (char *)NULL); + if (argc) { + if (freopen(argv[0], "r", stdin) == NULL) { + fprintf(stderr, "tk: cannot open %s\n", argv[0]); + exit(1); + } + } + signal(SIGINT, ex); + setbuf(stdout, obuf); + ncol = maxcol; + init(); + while ((i = getchar()) != EOF) { + switch(i) { + + case FF: + yy = 0; + case '\n': + xx = xoff; + yy -= LINE; + alpha = 0; + if (yy < yyll) { + ncol++; + yy = 0; + sendpt(0); + putchar(US); + fflush(stdout); + if (ncol >= maxcol) + kwait(); + init(); + } + continue; + + case CR: + xx = xoff; + alpha = 0; + continue; + + case ' ': + xx += 31; + alpha = 0; + continue; + + case '\t': /*tabstops at 8*31=248*/ + j = ((xx-xoff)/248) + 1; + xx += j*248 - (xx-xoff); + alpha = 0; + continue; + + case '\b': + xx -= 31; + alpha = 0; + continue; + + case ESC: + switch(i = getchar()) { + case '7': + yy += LINE; + alpha = 0; + continue; + case '8': + yy += (LINE + ry)/2; + ry = (LINE + ry)%2; + alpha = 0; + continue; + case '9': + yy -= (LINE - ry)/2; + ry = -(LINE - ry)%2; + alpha = 0; + continue; + default: + continue; + } + + default: + sendpt(alpha); + if (alpha==0) { + putchar(US); + alpha = 1; + } + putchar(i); + if (i>' ') + xx += 31; + continue; + } + } + xx = xoff; + yy = 0; + sendpt(0); + putchar(US); + kwait(); + ex(); +} + +init() +{ + ohx = oxb = olx = ohy = oly = -1; + if (ncol >= maxcol) { + ncol = 0; + if (maxcol > 1) + xoff = 0; + else + xoff = XOFF; + } else + xoff += coff; + xx = xoff; + yy = MAXY; + if (ncol==0) + fputs("\033\014\033;", stdout); + sendpt(0); +} + +ex() +{ + yy = MAXY; + xx = 0; + fputs("\033;\037", stdout); + sendpt(1); + exit(0); +} + +kwait() +{ + register c; + + fflush(stdout); + if (ttyin==NULL) + return; + while ((c=getc(ttyin))!='\n') { + if (c=='!') { + execom(); + printf("!\n"); + fflush(stdout); + continue; + } + if (c==EOF) + ex(); + } +} + +execom() +{ + int (*si)(), (*sq)(); + + if (fork() != 0) { + si = signal(SIGINT, SIG_IGN); + sq = signal(SIGQUIT, SIG_IGN); + wait((int *)NULL); + signal(SIGINT, si); + signal(SIGQUIT, sq); + return; + } + if (isatty(fileno(stdin)) == 0) { + if (freopen("/dev/tty", "r", stdin)==NULL) + freopen("/dev/null", "r", stdin); + } + execl("/bin/sh", "sh", "-t", 0); +} + +sendpt(a) +{ + register zz; + int hy,xb,ly,hx,lx; + + if (a) + return; + if ((zz = yy) < 0) + zz = 0; + hy = ((zz>>7) & 037); + xb = ((xx & 03) + ((zz<<2) & 014) & 017); + ly = ((zz>>2) & 037); + hx = ((xx>>7) & 037); + lx = ((xx>>2) & 037); + putchar(GS); + if (hy != ohy) + putchar(hy | 040); + if (xb != oxb) + putchar(xb | 0140); + if ((ly != oly) || (hx != ohx) || (xb != oxb)) + putchar(ly | 0140); + if (hx != ohx) + putchar(hx | 040); + putchar(lx | 0100); + ohy = hy; + oxb = xb; + oly = ly; + ohx = hx; + olx = lx; + alpha = 0; +} -- 2.20.1