Research V7 development
authorKen Thompson <ken@research.uucp>
Wed, 10 Jan 1979 20:01:40 +0000 (15:01 -0500)
committerKen Thompson <ken@research.uucp>
Wed, 10 Jan 1979 20:01:40 +0000 (15:01 -0500)
Work on file usr/src/cmd/ed.c
Work on file usr/src/cmd/file.c
Work on file usr/src/cmd/icheck.c
Work on file usr/src/cmd/iostat.c
Work on file usr/src/cmd/kill.c

Co-Authored-By: Dennis Ritchie <dmr@research.uucp>
Synthesized-from: v7

usr/src/cmd/ed.c [new file with mode: 0644]
usr/src/cmd/file.c [new file with mode: 0644]
usr/src/cmd/icheck.c [new file with mode: 0644]
usr/src/cmd/iostat.c [new file with mode: 0644]
usr/src/cmd/kill.c [new file with mode: 0644]

diff --git a/usr/src/cmd/ed.c b/usr/src/cmd/ed.c
new file mode 100644 (file)
index 0000000..c6bcf68
--- /dev/null
@@ -0,0 +1,1762 @@
+/*
+ * Editor
+ */
+
+#include <signal.h>
+#include <sgtty.h>
+#include <setjmp.h>
+#define        NULL    0
+#define        FNSIZE  64
+#define        LBSIZE  512
+#define        ESIZE   128
+#define        GBSIZE  256
+#define        NBRA    5
+#define        EOF     -1
+#define        KSIZE   9
+
+#define        CBRA    1
+#define        CCHR    2
+#define        CDOT    4
+#define        CCL     6
+#define        NCCL    8
+#define        CDOL    10
+#define        CEOF    11
+#define        CKET    12
+#define        CBACK   14
+
+#define        STAR    01
+
+char   Q[]     = "";
+char   T[]     = "TMP";
+#define        READ    0
+#define        WRITE   1
+
+int    peekc;
+int    lastc;
+char   savedfile[FNSIZE];
+char   file[FNSIZE];
+char   linebuf[LBSIZE];
+char   rhsbuf[LBSIZE/2];
+char   expbuf[ESIZE+4];
+int    circfl;
+int    *zero;
+int    *dot;
+int    *dol;
+int    *addr1;
+int    *addr2;
+char   genbuf[LBSIZE];
+long   count;
+char   *nextip;
+char   *linebp;
+int    ninbuf;
+int    io;
+int    pflag;
+long   lseek();
+int    (*oldhup)();
+int    (*oldquit)();
+int    vflag   = 1;
+int    xflag;
+int    xtflag;
+int    kflag;
+char   key[KSIZE + 1];
+char   crbuf[512];
+char   perm[768];
+char   tperm[768];
+int    listf;
+int    col;
+char   *globp;
+int    tfile   = -1;
+int    tline;
+char   *tfname;
+char   *loc1;
+char   *loc2;
+char   *locs;
+char   ibuff[512];
+int    iblock  = -1;
+char   obuff[512];
+int    oblock  = -1;
+int    ichanged;
+int    nleft;
+char   WRERR[] = "WRITE ERROR";
+int    names[26];
+int    anymarks;
+char   *braslist[NBRA];
+char   *braelist[NBRA];
+int    nbra;
+int    subnewa;
+int    subolda;
+int    fchange;
+int    wrapp;
+unsigned nlall = 128;
+
+int    *address();
+char   *getline();
+char   *getblock();
+char   *place();
+char   *mktemp();
+char   *malloc();
+char   *realloc();
+jmp_buf        savej;
+
+main(argc, argv)
+char **argv;
+{
+       register char *p1, *p2;
+       extern int onintr(), quit(), onhup();
+       int (*oldintr)();
+
+       oldquit = signal(SIGQUIT, SIG_IGN);
+       oldhup = signal(SIGHUP, SIG_IGN);
+       oldintr = signal(SIGINT, SIG_IGN);
+       if ((int)signal(SIGTERM, SIG_IGN) == 0)
+               signal(SIGTERM, quit);
+       argv++;
+       while (argc > 1 && **argv=='-') {
+               switch((*argv)[1]) {
+
+               case '\0':
+                       vflag = 0;
+                       break;
+
+               case 'q':
+                       signal(SIGQUIT, SIG_DFL);
+                       vflag = 1;
+                       break;
+
+               case 'x':
+                       xflag = 1;
+                       break;
+               }
+               argv++;
+               argc--;
+       }
+       if(xflag){
+               getkey();
+               kflag = crinit(key, perm);
+       }
+
+       if (argc>1) {
+               p1 = *argv;
+               p2 = savedfile;
+               while (*p2++ = *p1++)
+                       ;
+               globp = "r";
+       }
+       zero = (int *)malloc(nlall*sizeof(int));
+       tfname = mktemp("/tmp/eXXXXX");
+       init();
+       if (((int)oldintr&01) == 0)
+               signal(SIGINT, onintr);
+       if (((int)oldhup&01) == 0)
+               signal(SIGHUP, onhup);
+       setjmp(savej);
+       commands();
+       quit();
+}
+
+commands()
+{
+       int getfile(), gettty();
+       register *a1, c;
+
+       for (;;) {
+       if (pflag) {
+               pflag = 0;
+               addr1 = addr2 = dot;
+               goto print;
+       }
+       addr1 = 0;
+       addr2 = 0;
+       do {
+               addr1 = addr2;
+               if ((a1 = address())==0) {
+                       c = getchr();
+                       break;
+               }
+               addr2 = a1;
+               if ((c=getchr()) == ';') {
+                       c = ',';
+                       dot = a1;
+               }
+       } while (c==',');
+       if (addr1==0)
+               addr1 = addr2;
+       switch(c) {
+
+       case 'a':
+               setdot();
+               newline();
+               append(gettty, addr2);
+               continue;
+
+       case 'c':
+               delete();
+               append(gettty, addr1-1);
+               continue;
+
+       case 'd':
+               delete();
+               continue;
+
+       case 'E':
+               fchange = 0;
+               c = 'e';
+       case 'e':
+               setnoaddr();
+               if (vflag && fchange) {
+                       fchange = 0;
+                       error(Q);
+               }
+               filename(c);
+               init();
+               addr2 = zero;
+               goto caseread;
+
+       case 'f':
+               setnoaddr();
+               filename(c);
+               puts(savedfile);
+               continue;
+
+       case 'g':
+               global(1);
+               continue;
+
+       case 'i':
+               setdot();
+               nonzero();
+               newline();
+               append(gettty, addr2-1);
+               continue;
+
+
+       case 'j':
+               if (addr2==0) {
+                       addr1 = dot;
+                       addr2 = dot+1;
+               }
+               setdot();
+               newline();
+               nonzero();
+               join();
+               continue;
+
+       case 'k':
+               if ((c = getchr()) < 'a' || c > 'z')
+                       error(Q);
+               newline();
+               setdot();
+               nonzero();
+               names[c-'a'] = *addr2 & ~01;
+               anymarks |= 01;
+               continue;
+
+       case 'm':
+               move(0);
+               continue;
+
+       case '\n':
+               if (addr2==0)
+                       addr2 = dot+1;
+               addr1 = addr2;
+               goto print;
+
+       case 'l':
+               listf++;
+       case 'p':
+       case 'P':
+               newline();
+       print:
+               setdot();
+               nonzero();
+               a1 = addr1;
+               do {
+                       puts(getline(*a1++));
+               } while (a1 <= addr2);
+               dot = addr2;
+               listf = 0;
+               continue;
+
+       case 'Q':
+               fchange = 0;
+       case 'q':
+               setnoaddr();
+               newline();
+               quit();
+
+       case 'r':
+               filename(c);
+       caseread:
+               if ((io = open(file, 0)) < 0) {
+                       lastc = '\n';
+                       error(file);
+               }
+               setall();
+               ninbuf = 0;
+               c = zero != dol;
+               append(getfile, addr2);
+               exfile();
+               fchange = c;
+               continue;
+
+       case 's':
+               setdot();
+               nonzero();
+               substitute(globp!=0);
+               continue;
+
+       case 't':
+               move(1);
+               continue;
+
+       case 'u':
+               setdot();
+               nonzero();
+               newline();
+               if ((*addr2&~01) != subnewa)
+                       error(Q);
+               *addr2 = subolda;
+               dot = addr2;
+               continue;
+
+       case 'v':
+               global(0);
+               continue;
+
+       case 'W':
+               wrapp++;
+       case 'w':
+               setall();
+               nonzero();
+               filename(c);
+               if(!wrapp ||
+                 ((io = open(file,1)) == -1) ||
+                 ((lseek(io, 0L, 2)) == -1))
+                       if ((io = creat(file, 0666)) < 0)
+                               error(file);
+               wrapp = 0;
+               putfile();
+               exfile();
+               if (addr1==zero+1 && addr2==dol)
+                       fchange = 0;
+               continue;
+
+       case 'x':
+               setnoaddr();
+               newline();
+               xflag = 1;
+               puts("Entering encrypting mode!");
+               getkey();
+               kflag = crinit(key, perm);
+               continue;
+
+
+       case '=':
+               setall();
+               newline();
+               count = (addr2-zero)&077777;
+               putd();
+               putchr('\n');
+               continue;
+
+       case '!':
+               callunix();
+               continue;
+
+       case EOF:
+               return;
+
+       }
+       error(Q);
+       }
+}
+
+int *
+address()
+{
+       register *a1, minus, c;
+       int n, relerr;
+
+       minus = 0;
+       a1 = 0;
+       for (;;) {
+               c = getchr();
+               if ('0'<=c && c<='9') {
+                       n = 0;
+                       do {
+                               n *= 10;
+                               n += c - '0';
+                       } while ((c = getchr())>='0' && c<='9');
+                       peekc = c;
+                       if (a1==0)
+                               a1 = zero;
+                       if (minus<0)
+                               n = -n;
+                       a1 += n;
+                       minus = 0;
+                       continue;
+               }
+               relerr = 0;
+               if (a1 || minus)
+                       relerr++;
+               switch(c) {
+               case ' ':
+               case '\t':
+                       continue;
+       
+               case '+':
+                       minus++;
+                       if (a1==0)
+                               a1 = dot;
+                       continue;
+
+               case '-':
+               case '^':
+                       minus--;
+                       if (a1==0)
+                               a1 = dot;
+                       continue;
+       
+               case '?':
+               case '/':
+                       compile(c);
+                       a1 = dot;
+                       for (;;) {
+                               if (c=='/') {
+                                       a1++;
+                                       if (a1 > dol)
+                                               a1 = zero;
+                               } else {
+                                       a1--;
+                                       if (a1 < zero)
+                                               a1 = dol;
+                               }
+                               if (execute(0, a1))
+                                       break;
+                               if (a1==dot)
+                                       error(Q);
+                       }
+                       break;
+       
+               case '$':
+                       a1 = dol;
+                       break;
+       
+               case '.':
+                       a1 = dot;
+                       break;
+
+               case '\'':
+                       if ((c = getchr()) < 'a' || c > 'z')
+                               error(Q);
+                       for (a1=zero; a1<=dol; a1++)
+                               if (names[c-'a'] == (*a1 & ~01))
+                                       break;
+                       break;
+       
+               default:
+                       peekc = c;
+                       if (a1==0)
+                               return(0);
+                       a1 += minus;
+                       if (a1<zero || a1>dol)
+                               error(Q);
+                       return(a1);
+               }
+               if (relerr)
+                       error(Q);
+       }
+}
+
+setdot()
+{
+       if (addr2 == 0)
+               addr1 = addr2 = dot;
+       if (addr1 > addr2)
+               error(Q);
+}
+
+setall()
+{
+       if (addr2==0) {
+               addr1 = zero+1;
+               addr2 = dol;
+               if (dol==zero)
+                       addr1 = zero;
+       }
+       setdot();
+}
+
+setnoaddr()
+{
+       if (addr2)
+               error(Q);
+}
+
+nonzero()
+{
+       if (addr1<=zero || addr2>dol)
+               error(Q);
+}
+
+newline()
+{
+       register c;
+
+       if ((c = getchr()) == '\n')
+               return;
+       if (c=='p' || c=='l') {
+               pflag++;
+               if (c=='l')
+                       listf++;
+               if (getchr() == '\n')
+                       return;
+       }
+       error(Q);
+}
+
+filename(comm)
+{
+       register char *p1, *p2;
+       register c;
+
+       count = 0;
+       c = getchr();
+       if (c=='\n' || c==EOF) {
+               p1 = savedfile;
+               if (*p1==0 && comm!='f')
+                       error(Q);
+               p2 = file;
+               while (*p2++ = *p1++)
+                       ;
+               return;
+       }
+       if (c!=' ')
+               error(Q);
+       while ((c = getchr()) == ' ')
+               ;
+       if (c=='\n')
+               error(Q);
+       p1 = file;
+       do {
+               *p1++ = c;
+               if (c==' ' || c==EOF)
+                       error(Q);
+       } while ((c = getchr()) != '\n');
+       *p1++ = 0;
+       if (savedfile[0]==0 || comm=='e' || comm=='f') {
+               p1 = savedfile;
+               p2 = file;
+               while (*p1++ = *p2++)
+                       ;
+       }
+}
+
+exfile()
+{
+       close(io);
+       io = -1;
+       if (vflag) {
+               putd();
+               putchr('\n');
+       }
+}
+
+onintr()
+{
+       signal(SIGINT, onintr);
+       putchr('\n');
+       lastc = '\n';
+       error(Q);
+}
+
+onhup()
+{
+       signal(SIGINT, SIG_IGN);
+       signal(SIGHUP, SIG_IGN);
+       if (dol > zero) {
+               addr1 = zero+1;
+               addr2 = dol;
+               io = creat("ed.hup", 0666);
+               if (io > 0)
+                       putfile();
+       }
+       fchange = 0;
+       quit();
+}
+
+error(s)
+char *s;
+{
+       register c;
+
+       wrapp = 0;
+       listf = 0;
+       putchr('?');
+       puts(s);
+       count = 0;
+       lseek(0, (long)0, 2);
+       pflag = 0;
+       if (globp)
+               lastc = '\n';
+       globp = 0;
+       peekc = lastc;
+       if(lastc)
+               while ((c = getchr()) != '\n' && c != EOF)
+                       ;
+       if (io > 0) {
+               close(io);
+               io = -1;
+       }
+       longjmp(savej, 1);
+}
+
+getchr()
+{
+       char c;
+       if (lastc=peekc) {
+               peekc = 0;
+               return(lastc);
+       }
+       if (globp) {
+               if ((lastc = *globp++) != 0)
+                       return(lastc);
+               globp = 0;
+               return(EOF);
+       }
+       if (read(0, &c, 1) <= 0)
+               return(lastc = EOF);
+       lastc = c&0177;
+       return(lastc);
+}
+
+gettty()
+{
+       register c;
+       register char *gf;
+       register char *p;
+
+       p = linebuf;
+       gf = globp;
+       while ((c = getchr()) != '\n') {
+               if (c==EOF) {
+                       if (gf)
+                               peekc = c;
+                       return(c);
+               }
+               if ((c &= 0177) == 0)
+                       continue;
+               *p++ = c;
+               if (p >= &linebuf[LBSIZE-2])
+                       error(Q);
+       }
+       *p++ = 0;
+       if (linebuf[0]=='.' && linebuf[1]==0)
+               return(EOF);
+       return(0);
+}
+
+getfile()
+{
+       register c;
+       register char *lp, *fp;
+
+       lp = linebuf;
+       fp = nextip;
+       do {
+               if (--ninbuf < 0) {
+                       if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0)
+                               return(EOF);
+                       fp = genbuf;
+                       while(fp < &genbuf[ninbuf]) {
+                               if (*fp++ & 0200) {
+                                       if (kflag)
+                                               crblock(perm, genbuf, ninbuf+1, count);
+                                       break;
+                               }
+                       }
+                       fp = genbuf;
+               }
+               c = *fp++;
+               if (c=='\0')
+                       continue;
+               if (c&0200 || lp >= &linebuf[LBSIZE]) {
+                       lastc = '\n';
+                       error(Q);
+               }
+               *lp++ = c;
+               count++;
+       } while (c != '\n');
+       *--lp = 0;
+       nextip = fp;
+       return(0);
+}
+
+putfile()
+{
+       int *a1, n;
+       register char *fp, *lp;
+       register nib;
+
+       nib = 512;
+       fp = genbuf;
+       a1 = addr1;
+       do {
+               lp = getline(*a1++);
+               for (;;) {
+                       if (--nib < 0) {
+                               n = fp-genbuf;
+                               if(kflag)
+                                       crblock(perm, genbuf, n, count-n);
+                               if(write(io, genbuf, n) != n) {
+                                       puts(WRERR);
+                                       error(Q);
+                               }
+                               nib = 511;
+                               fp = genbuf;
+                       }
+                       count++;
+                       if ((*fp++ = *lp++) == 0) {
+                               fp[-1] = '\n';
+                               break;
+                       }
+               }
+       } while (a1 <= addr2);
+       n = fp-genbuf;
+       if(kflag)
+               crblock(perm, genbuf, n, count-n);
+       if(write(io, genbuf, n) != n) {
+               puts(WRERR);
+               error(Q);
+       }
+}
+
+append(f, a)
+int *a;
+int (*f)();
+{
+       register *a1, *a2, *rdot;
+       int nline, tl;
+
+       nline = 0;
+       dot = a;
+       while ((*f)() == 0) {
+               if ((dol-zero)+1 >= nlall) {
+                       int *ozero = zero;
+                       nlall += 512;
+                       free((char *)zero);
+                       if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) {
+                               lastc = '\n';
+                               zero = ozero;
+                               error("MEM?");
+                       }
+                       dot += zero - ozero;
+                       dol += zero - ozero;
+               }
+               tl = putline();
+               nline++;
+               a1 = ++dol;
+               a2 = a1+1;
+               rdot = ++dot;
+               while (a1 > rdot)
+                       *--a2 = *--a1;
+               *rdot = tl;
+       }
+       return(nline);
+}
+
+callunix()
+{
+       register (*savint)(), pid, rpid;
+       int retcode;
+
+       setnoaddr();
+       if ((pid = fork()) == 0) {
+               signal(SIGHUP, oldhup);
+               signal(SIGQUIT, oldquit);
+               execl("/bin/sh", "sh", "-t", 0);
+               exit(0100);
+       }
+       savint = signal(SIGINT, SIG_IGN);
+       while ((rpid = wait(&retcode)) != pid && rpid != -1)
+               ;
+       signal(SIGINT, savint);
+       puts("!");
+}
+
+quit()
+{
+       if (vflag && fchange && dol!=zero) {
+               fchange = 0;
+               error(Q);
+       }
+       unlink(tfname);
+       exit(0);
+}
+
+delete()
+{
+       setdot();
+       newline();
+       nonzero();
+       rdelete(addr1, addr2);
+}
+
+rdelete(ad1, ad2)
+int *ad1, *ad2;
+{
+       register *a1, *a2, *a3;
+
+       a1 = ad1;
+       a2 = ad2+1;
+       a3 = dol;
+       dol -= a2 - a1;
+       do {
+               *a1++ = *a2++;
+       } while (a2 <= a3);
+       a1 = ad1;
+       if (a1 > dol)
+               a1 = dol;
+       dot = a1;
+       fchange = 1;
+}
+
+gdelete()
+{
+       register *a1, *a2, *a3;
+
+       a3 = dol;
+       for (a1=zero+1; (*a1&01)==0; a1++)
+               if (a1>=a3)
+                       return;
+       for (a2=a1+1; a2<=a3;) {
+               if (*a2&01) {
+                       a2++;
+                       dot = a1;
+               } else
+                       *a1++ = *a2++;
+       }
+       dol = a1-1;
+       if (dot>dol)
+               dot = dol;
+       fchange = 1;
+}
+
+char *
+getline(tl)
+{
+       register char *bp, *lp;
+       register nl;
+
+       lp = linebuf;
+       bp = getblock(tl, READ);
+       nl = nleft;
+       tl &= ~0377;
+       while (*lp++ = *bp++)
+               if (--nl == 0) {
+                       bp = getblock(tl+=0400, READ);
+                       nl = nleft;
+               }
+       return(linebuf);
+}
+
+putline()
+{
+       register char *bp, *lp;
+       register nl;
+       int tl;
+
+       fchange = 1;
+       lp = linebuf;
+       tl = tline;
+       bp = getblock(tl, WRITE);
+       nl = nleft;
+       tl &= ~0377;
+       while (*bp = *lp++) {
+               if (*bp++ == '\n') {
+                       *--bp = 0;
+                       linebp = lp;
+                       break;
+               }
+               if (--nl == 0) {
+                       bp = getblock(tl+=0400, WRITE);
+                       nl = nleft;
+               }
+       }
+       nl = tline;
+       tline += (((lp-linebuf)+03)>>1)&077776;
+       return(nl);
+}
+
+char *
+getblock(atl, iof)
+{
+       extern read(), write();
+       register bno, off;
+       register char *p1, *p2;
+       register int n;
+       
+       bno = (atl>>8)&0377;
+       off = (atl<<1)&0774;
+       if (bno >= 255) {
+               lastc = '\n';
+               error(T);
+       }
+       nleft = 512 - off;
+       if (bno==iblock) {
+               ichanged |= iof;
+               return(ibuff+off);
+       }
+       if (bno==oblock)
+               return(obuff+off);
+       if (iof==READ) {
+               if (ichanged) {
+                       if(xtflag)
+                               crblock(tperm, ibuff, 512, (long)0);
+                       blkio(iblock, ibuff, write);
+               }
+               ichanged = 0;
+               iblock = bno;
+               blkio(bno, ibuff, read);
+               if(xtflag)
+                       crblock(tperm, ibuff, 512, (long)0);
+               return(ibuff+off);
+       }
+       if (oblock>=0) {
+               if(xtflag) {
+                       p1 = obuff;
+                       p2 = crbuf;
+                       n = 512;
+                       while(n--)
+                               *p2++ = *p1++;
+                       crblock(tperm, crbuf, 512, (long)0);
+                       blkio(oblock, crbuf, write);
+               } else
+                       blkio(oblock, obuff, write);
+       }
+       oblock = bno;
+       return(obuff+off);
+}
+
+blkio(b, buf, iofcn)
+char *buf;
+int (*iofcn)();
+{
+       lseek(tfile, (long)b<<9, 0);
+       if ((*iofcn)(tfile, buf, 512) != 512) {
+               error(T);
+       }
+}
+
+init()
+{
+       register *markp;
+
+       close(tfile);
+       tline = 2;
+       for (markp = names; markp < &names[26]; )
+               *markp++ = 0;
+       subnewa = 0;
+       anymarks = 0;
+       iblock = -1;
+       oblock = -1;
+       ichanged = 0;
+       close(creat(tfname, 0600));
+       tfile = open(tfname, 2);
+       if(xflag) {
+               xtflag = 1;
+               makekey(key, tperm);
+       }
+       dot = dol = zero;
+}
+
+global(k)
+{
+       register char *gp;
+       register c;
+       register int *a1;
+       char globuf[GBSIZE];
+
+       if (globp)
+               error(Q);
+       setall();
+       nonzero();
+       if ((c=getchr())=='\n')
+               error(Q);
+       compile(c);
+       gp = globuf;
+       while ((c = getchr()) != '\n') {
+               if (c==EOF)
+                       error(Q);
+               if (c=='\\') {
+                       c = getchr();
+                       if (c!='\n')
+                               *gp++ = '\\';
+               }
+               *gp++ = c;
+               if (gp >= &globuf[GBSIZE-2])
+                       error(Q);
+       }
+       *gp++ = '\n';
+       *gp++ = 0;
+       for (a1=zero; a1<=dol; a1++) {
+               *a1 &= ~01;
+               if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k)
+                       *a1 |= 01;
+       }
+       /*
+        * Special case: g/.../d (avoid n^2 algorithm)
+        */
+       if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') {
+               gdelete();
+               return;
+       }
+       for (a1=zero; a1<=dol; a1++) {
+               if (*a1 & 01) {
+                       *a1 &= ~01;
+                       dot = a1;
+                       globp = globuf;
+                       commands();
+                       a1 = zero;
+               }
+       }
+}
+
+join()
+{
+       register char *gp, *lp;
+       register *a1;
+
+       gp = genbuf;
+       for (a1=addr1; a1<=addr2; a1++) {
+               lp = getline(*a1);
+               while (*gp = *lp++)
+                       if (gp++ >= &genbuf[LBSIZE-2])
+                               error(Q);
+       }
+       lp = linebuf;
+       gp = genbuf;
+       while (*lp++ = *gp++)
+               ;
+       *addr1 = putline();
+       if (addr1<addr2)
+               rdelete(addr1+1, addr2);
+       dot = addr1;
+}
+
+substitute(inglob)
+{
+       register *markp, *a1, nl;
+       int gsubf;
+       int getsub();
+
+       gsubf = compsub();
+       for (a1 = addr1; a1 <= addr2; a1++) {
+               int *ozero;
+               if (execute(0, a1)==0)
+                       continue;
+               inglob |= 01;
+               dosub();
+               if (gsubf) {
+                       while (*loc2) {
+                               if (execute(1, (int *)0)==0)
+                                       break;
+                               dosub();
+                       }
+               }
+               subnewa = putline();
+               *a1 &= ~01;
+               if (anymarks) {
+                       for (markp = names; markp < &names[26]; markp++)
+                               if (*markp == *a1)
+                                       *markp = subnewa;
+               }
+               subolda = *a1;
+               *a1 = subnewa;
+               ozero = zero;
+               nl = append(getsub, a1);
+               nl += zero-ozero;
+               a1 += nl;
+               addr2 += nl;
+       }
+       if (inglob==0)
+               error(Q);
+}
+
+compsub()
+{
+       register seof, c;
+       register char *p;
+
+       if ((seof = getchr()) == '\n' || seof == ' ')
+               error(Q);
+       compile(seof);
+       p = rhsbuf;
+       for (;;) {
+               c = getchr();
+               if (c=='\\')
+                       c = getchr() | 0200;
+               if (c=='\n') {
+                       if (globp)
+                               c |= 0200;
+                       else
+                               error(Q);
+               }
+               if (c==seof)
+                       break;
+               *p++ = c;
+               if (p >= &rhsbuf[LBSIZE/2])
+                       error(Q);
+       }
+       *p++ = 0;
+       if ((peekc = getchr()) == 'g') {
+               peekc = 0;
+               newline();
+               return(1);
+       }
+       newline();
+       return(0);
+}
+
+getsub()
+{
+       register char *p1, *p2;
+
+       p1 = linebuf;
+       if ((p2 = linebp) == 0)
+               return(EOF);
+       while (*p1++ = *p2++)
+               ;
+       linebp = 0;
+       return(0);
+}
+
+dosub()
+{
+       register char *lp, *sp, *rp;
+       int c;
+
+       lp = linebuf;
+       sp = genbuf;
+       rp = rhsbuf;
+       while (lp < loc1)
+               *sp++ = *lp++;
+       while (c = *rp++&0377) {
+               if (c=='&') {
+                       sp = place(sp, loc1, loc2);
+                       continue;
+               } else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') {
+                       sp = place(sp, braslist[c-'1'], braelist[c-'1']);
+                       continue;
+               }
+               *sp++ = c&0177;
+               if (sp >= &genbuf[LBSIZE])
+                       error(Q);
+       }
+       lp = loc2;
+       loc2 = sp - genbuf + linebuf;
+       while (*sp++ = *lp++)
+               if (sp >= &genbuf[LBSIZE])
+                       error(Q);
+       lp = linebuf;
+       sp = genbuf;
+       while (*lp++ = *sp++)
+               ;
+}
+
+char *
+place(sp, l1, l2)
+register char *sp, *l1, *l2;
+{
+
+       while (l1 < l2) {
+               *sp++ = *l1++;
+               if (sp >= &genbuf[LBSIZE])
+                       error(Q);
+       }
+       return(sp);
+}
+
+move(cflag)
+{
+       register int *adt, *ad1, *ad2;
+       int getcopy();
+
+       setdot();
+       nonzero();
+       if ((adt = address())==0)
+               error(Q);
+       newline();
+       if (cflag) {
+               int *ozero, delta;
+               ad1 = dol;
+               ozero = zero;
+               append(getcopy, ad1++);
+               ad2 = dol;
+               delta = zero - ozero;
+               ad1 += delta;
+               adt += delta;
+       } else {
+               ad2 = addr2;
+               for (ad1 = addr1; ad1 <= ad2;)
+                       *ad1++ &= ~01;
+               ad1 = addr1;
+       }
+       ad2++;
+       if (adt<ad1) {
+               dot = adt + (ad2-ad1);
+               if ((++adt)==ad1)
+                       return;
+               reverse(adt, ad1);
+               reverse(ad1, ad2);
+               reverse(adt, ad2);
+       } else if (adt >= ad2) {
+               dot = adt++;
+               reverse(ad1, ad2);
+               reverse(ad2, adt);
+               reverse(ad1, adt);
+       } else
+               error(Q);
+       fchange = 1;
+}
+
+reverse(a1, a2)
+register int *a1, *a2;
+{
+       register int t;
+
+       for (;;) {
+               t = *--a2;
+               if (a2 <= a1)
+                       return;
+               *a2 = *a1;
+               *a1++ = t;
+       }
+}
+
+getcopy()
+{
+       if (addr1 > addr2)
+               return(EOF);
+       getline(*addr1++);
+       return(0);
+}
+
+compile(aeof)
+{
+       register eof, c;
+       register char *ep;
+       char *lastep;
+       char bracket[NBRA], *bracketp;
+       int cclcnt;
+
+       ep = expbuf;
+       eof = aeof;
+       bracketp = bracket;
+       if ((c = getchr()) == eof) {
+               if (*ep==0)
+                       error(Q);
+               return;
+       }
+       circfl = 0;
+       nbra = 0;
+       if (c=='^') {
+               c = getchr();
+               circfl++;
+       }
+       peekc = c;
+       lastep = 0;
+       for (;;) {
+               if (ep >= &expbuf[ESIZE])
+                       goto cerror;
+               c = getchr();
+               if (c==eof) {
+                       if (bracketp != bracket)
+                               goto cerror;
+                       *ep++ = CEOF;
+                       return;
+               }
+               if (c!='*')
+                       lastep = ep;
+               switch (c) {
+
+               case '\\':
+                       if ((c = getchr())=='(') {
+                               if (nbra >= NBRA)
+                                       goto cerror;
+                               *bracketp++ = nbra;
+                               *ep++ = CBRA;
+                               *ep++ = nbra++;
+                               continue;
+                       }
+                       if (c == ')') {
+                               if (bracketp <= bracket)
+                                       goto cerror;
+                               *ep++ = CKET;
+                               *ep++ = *--bracketp;
+                               continue;
+                       }
+                       if (c>='1' && c<'1'+NBRA) {
+                               *ep++ = CBACK;
+                               *ep++ = c-'1';
+                               continue;
+                       }
+                       *ep++ = CCHR;
+                       if (c=='\n')
+                               goto cerror;
+                       *ep++ = c;
+                       continue;
+
+               case '.':
+                       *ep++ = CDOT;
+                       continue;
+
+               case '\n':
+                       goto cerror;
+
+               case '*':
+                       if (lastep==0 || *lastep==CBRA || *lastep==CKET)
+                               goto defchar;
+                       *lastep |= STAR;
+                       continue;
+
+               case '$':
+                       if ((peekc=getchr()) != eof)
+                               goto defchar;
+                       *ep++ = CDOL;
+                       continue;
+
+               case '[':
+                       *ep++ = CCL;
+                       *ep++ = 0;
+                       cclcnt = 1;
+                       if ((c=getchr()) == '^') {
+                               c = getchr();
+                               ep[-2] = NCCL;
+                       }
+                       do {
+                               if (c=='\n')
+                                       goto cerror;
+                               if (c=='-' && ep[-1]!=0) {
+                                       if ((c=getchr())==']') {
+                                               *ep++ = '-';
+                                               cclcnt++;
+                                               break;
+                                       }
+                                       while (ep[-1]<c) {
+                                               *ep = ep[-1]+1;
+                                               ep++;
+                                               cclcnt++;
+                                               if (ep>=&expbuf[ESIZE])
+                                                       goto cerror;
+                                       }
+                               }
+                               *ep++ = c;
+                               cclcnt++;
+                               if (ep >= &expbuf[ESIZE])
+                                       goto cerror;
+                       } while ((c = getchr()) != ']');
+                       lastep[1] = cclcnt;
+                       continue;
+
+               defchar:
+               default:
+                       *ep++ = CCHR;
+                       *ep++ = c;
+               }
+       }
+   cerror:
+       expbuf[0] = 0;
+       nbra = 0;
+       error(Q);
+}
+
+execute(gf, addr)
+int *addr;
+{
+       register char *p1, *p2, c;
+
+       for (c=0; c<NBRA; c++) {
+               braslist[c] = 0;
+               braelist[c] = 0;
+       }
+       if (gf) {
+               if (circfl)
+                       return(0);
+               p1 = linebuf;
+               p2 = genbuf;
+               while (*p1++ = *p2++)
+                       ;
+               locs = p1 = loc2;
+       } else {
+               if (addr==zero)
+                       return(0);
+               p1 = getline(*addr);
+               locs = 0;
+       }
+       p2 = expbuf;
+       if (circfl) {
+               loc1 = p1;
+               return(advance(p1, p2));
+       }
+       /* fast check for first character */
+       if (*p2==CCHR) {
+               c = p2[1];
+               do {
+                       if (*p1!=c)
+                               continue;
+                       if (advance(p1, p2)) {
+                               loc1 = p1;
+                               return(1);
+                       }
+               } while (*p1++);
+               return(0);
+       }
+       /* regular algorithm */
+       do {
+               if (advance(p1, p2)) {
+                       loc1 = p1;
+                       return(1);
+               }
+       } while (*p1++);
+       return(0);
+}
+
+advance(lp, ep)
+register char *ep, *lp;
+{
+       register char *curlp;
+       int i;
+
+       for (;;) switch (*ep++) {
+
+       case CCHR:
+               if (*ep++ == *lp++)
+                       continue;
+               return(0);
+
+       case CDOT:
+               if (*lp++)
+                       continue;
+               return(0);
+
+       case CDOL:
+               if (*lp==0)
+                       continue;
+               return(0);
+
+       case CEOF:
+               loc2 = lp;
+               return(1);
+
+       case CCL:
+               if (cclass(ep, *lp++, 1)) {
+                       ep += *ep;
+                       continue;
+               }
+               return(0);
+
+       case NCCL:
+               if (cclass(ep, *lp++, 0)) {
+                       ep += *ep;
+                       continue;
+               }
+               return(0);
+
+       case CBRA:
+               braslist[*ep++] = lp;
+               continue;
+
+       case CKET:
+               braelist[*ep++] = lp;
+               continue;
+
+       case CBACK:
+               if (braelist[i = *ep++]==0)
+                       error(Q);
+               if (backref(i, lp)) {
+                       lp += braelist[i] - braslist[i];
+                       continue;
+               }
+               return(0);
+
+       case CBACK|STAR:
+               if (braelist[i = *ep++] == 0)
+                       error(Q);
+               curlp = lp;
+               while (backref(i, lp))
+                       lp += braelist[i] - braslist[i];
+               while (lp >= curlp) {
+                       if (advance(lp, ep))
+                               return(1);
+                       lp -= braelist[i] - braslist[i];
+               }
+               continue;
+
+       case CDOT|STAR:
+               curlp = lp;
+               while (*lp++)
+                       ;
+               goto star;
+
+       case CCHR|STAR:
+               curlp = lp;
+               while (*lp++ == *ep)
+                       ;
+               ep++;
+               goto star;
+
+       case CCL|STAR:
+       case NCCL|STAR:
+               curlp = lp;
+               while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)))
+                       ;
+               ep += *ep;
+               goto star;
+
+       star:
+               do {
+                       lp--;
+                       if (lp==locs)
+                               break;
+                       if (advance(lp, ep))
+                               return(1);
+               } while (lp > curlp);
+               return(0);
+
+       default:
+               error(Q);
+       }
+}
+
+backref(i, lp)
+register i;
+register char *lp;
+{
+       register char *bp;
+
+       bp = braslist[i];
+       while (*bp++ == *lp++)
+               if (bp >= braelist[i])
+                       return(1);
+       return(0);
+}
+
+cclass(set, c, af)
+register char *set, c;
+{
+       register n;
+
+       if (c==0)
+               return(0);
+       n = *set++;
+       while (--n)
+               if (*set++ == c)
+                       return(af);
+       return(!af);
+}
+
+putd()
+{
+       register r;
+
+       r = count%10;
+       count /= 10;
+       if (count)
+               putd();
+       putchr(r + '0');
+}
+
+puts(sp)
+register char *sp;
+{
+       col = 0;
+       while (*sp)
+               putchr(*sp++);
+       putchr('\n');
+}
+
+char   line[70];
+char   *linp   = line;
+
+putchr(ac)
+{
+       register char *lp;
+       register c;
+
+       lp = linp;
+       c = ac;
+       if (listf) {
+               col++;
+               if (col >= 72) {
+                       col = 0;
+                       *lp++ = '\\';
+                       *lp++ = '\n';
+               }
+               if (c=='\t') {
+                       c = '>';
+                       goto esc;
+               }
+               if (c=='\b') {
+                       c = '<';
+               esc:
+                       *lp++ = '-';
+                       *lp++ = '\b';
+                       *lp++ = c;
+                       goto out;
+               }
+               if (c<' ' && c!= '\n') {
+                       *lp++ = '\\';
+                       *lp++ = (c>>3)+'0';
+                       *lp++ = (c&07)+'0';
+                       col += 2;
+                       goto out;
+               }
+       }
+       *lp++ = c;
+out:
+       if(c == '\n' || lp >= &line[64]) {
+               linp = line;
+               write(1, line, lp-line);
+               return;
+       }
+       linp = lp;
+}
+crblock(permp, buf, nchar, startn)
+char *permp;
+char *buf;
+long startn;
+{
+       register char *p1;
+       int n1;
+       int n2;
+       register char *t1, *t2, *t3;
+
+       t1 = permp;
+       t2 = &permp[256];
+       t3 = &permp[512];
+
+       n1 = startn&0377;
+       n2 = (startn>>8)&0377;
+       p1 = buf;
+       while(nchar--) {
+               *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
+               n1++;
+               if(n1==256){
+                       n1 = 0;
+                       n2++;
+                       if(n2==256) n2 = 0;
+               }
+               p1++;
+       }
+}
+
+getkey()
+{
+       struct sgttyb b;
+       int save;
+       int (*sig)();
+       register char *p;
+       register c;
+
+       sig = signal(SIGINT, SIG_IGN);
+       if (gtty(0, &b) == -1)
+               error("Input not tty");
+       save = b.sg_flags;
+       b.sg_flags &= ~ECHO;
+       stty(0, &b);
+       puts("Key:");
+       p = key;
+       while(((c=getchr()) != EOF) && (c!='\n')) {
+               if(p < &key[KSIZE])
+                       *p++ = c;
+       }
+       *p = 0;
+       b.sg_flags = save;
+       stty(0, &b);
+       signal(SIGINT, sig);
+       return(key[0] != 0);
+}
+
+/*
+ * Besides initializing the encryption machine, this routine
+ * returns 0 if the key is null, and 1 if it is non-null.
+ */
+crinit(keyp, permp)
+char   *keyp, *permp;
+{
+       register char *t1, *t2, *t3;
+       register i;
+       int ic, k, temp, pf[2];
+       unsigned random;
+       char buf[13];
+       long seed;
+
+       t1 = permp;
+       t2 = &permp[256];
+       t3 = &permp[512];
+       if(*keyp == 0)
+               return(0);
+       strncpy(buf, keyp, 8);
+       while (*keyp)
+               *keyp++ = '\0';
+       buf[8] = buf[0];
+       buf[9] = buf[1];
+       if (pipe(pf)<0)
+               pf[0] = pf[1] = -1;
+       if (fork()==0) {
+               close(0);
+               close(1);
+               dup(pf[0]);
+               dup(pf[1]);
+               execl("/usr/lib/makekey", "-", 0);
+               execl("/lib/makekey", "-", 0);
+               exit(1);
+       }
+       write(pf[1], buf, 10);
+       if (wait((int *)NULL)==-1 || read(pf[0], buf, 13)!=13)
+               error("crypt: cannot generate key");
+       close(pf[0]);
+       close(pf[1]);
+       seed = 123;
+       for (i=0; i<13; i++)
+               seed = seed*buf[i] + i;
+       for(i=0;i<256;i++){
+               t1[i] = i;
+               t3[i] = 0;
+       }
+       for(i=0; i<256; i++) {
+               seed = 5*seed + buf[i%13];
+               random = seed % 65521;
+               k = 256-1 - i;
+               ic = (random&0377) % (k+1);
+               random >>= 8;
+               temp = t1[k];
+               t1[k] = t1[ic];
+               t1[ic] = temp;
+               if(t3[k]!=0) continue;
+               ic = (random&0377) % k;
+               while(t3[ic]!=0) ic = (ic+1) % k;
+               t3[k] = ic;
+               t3[ic] = k;
+       }
+       for(i=0; i<256; i++)
+               t2[t1[i]&0377] = i;
+       return(1);
+}
+
+makekey(a, b)
+char *a, *b;
+{
+       register int i;
+       long t;
+       char temp[KSIZE + 1];
+
+       for(i = 0; i < KSIZE; i++)
+               temp[i] = *a++;
+       time(&t);
+       t += getpid();
+       for(i = 0; i < 4; i++)
+               temp[i] ^= (t>>(8*i))&0377;
+       crinit(temp, b);
+}
diff --git a/usr/src/cmd/file.c b/usr/src/cmd/file.c
new file mode 100644 (file)
index 0000000..b431a4a
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * determine type of file
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <ctype.h>
+int in;
+int i  = 0;
+char buf[512];
+char *fort[] = {
+       "function","subroutine","common","dimension","block","integer",
+       "real","data","double",0};
+char *asc[] = {
+       "sys","mov","tst","clr","jmp",0};
+char *c[] = {
+       "int","char","float","double","struct","extern",0};
+char *as[] = {
+       "globl","byte","even","text","data","bss","comm",0};
+int    ifile;
+
+main(argc, argv)
+char **argv;
+{
+       FILE *fl;
+       register char *p;
+       char ap[128];
+
+       if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') {
+               if ((fl = fopen(argv[2], "r")) == NULL) {
+                       printf("Can't open %s\n", argv[2]);
+                       exit(2);
+               }
+               while ((p = fgets(ap, 128, fl)) != NULL) {
+                       int l = strlen(p);
+                       if (l>0)
+                               p[l-1] = '\0';
+                       printf("%s:     ", p);
+                       type(p);
+                       if (ifile>=0)
+                               close(ifile);
+               }
+               exit(1);
+       }
+       while(argc > 1) {
+               printf("%s:     ", argv[1]);
+               type(argv[1]);
+               argc--;
+               argv++;
+               if (ifile >= 0)
+                       close(ifile);
+       }
+}
+
+type(file)
+char *file;
+{
+       int j,nl;
+       char ch;
+       struct stat mbuf;
+
+       ifile = -1;
+       if(stat(file, &mbuf) < 0) {
+               printf("cannot stat\n");
+               return;
+       }
+       switch (mbuf.st_mode & S_IFMT) {
+
+       case S_IFCHR:
+               printf("character");
+               goto spcl;
+
+       case S_IFDIR:
+               printf("directory\n");
+               return;
+
+       case S_IFBLK:
+               printf("block");
+
+spcl:
+               printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev));
+               return;
+       }
+
+       ifile = open(file, 0);
+       if(ifile < 0) {
+               printf("cannot open\n");
+               return;
+       }
+       in = read(ifile, buf, 512);
+       if(in == 0){
+               printf("empty\n");
+               return;
+       }
+       switch(*(int *)buf) {
+
+       case 0410:
+               printf("pure ");
+               goto exec;
+
+       case 0411:
+               printf("separate ");
+
+       case 0407:
+exec:
+               printf("executable");
+               if(((int *)buf)[4] != 0)
+                       printf(" not stripped");
+               printf("\n");
+               goto out;
+
+       case 0177555:
+               printf("old archive\n");
+               goto out;
+
+       case 0177545:
+               printf("archive\n");
+               goto out;
+       }
+
+       i = 0;
+       if(ccom() == 0)goto notc;
+       while(buf[i] == '#'){
+               j = i;
+               while(buf[i++] != '\n'){
+                       if(i - j > 255){
+                               printf("data\n"); 
+                               goto out;
+                       }
+                       if(i >= in)goto notc;
+               }
+               if(ccom() == 0)goto notc;
+       }
+check:
+       if(lookup(c) == 1){
+               while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
+               printf("c program text");
+               goto outa;
+       }
+       nl = 0;
+       while(buf[i] != '('){
+               if(buf[i] <= 0)
+                       goto notas;
+               if(buf[i] == ';'){
+                       i++; 
+                       goto check; 
+               }
+               if(buf[i++] == '\n')
+                       if(nl++ > 6)goto notc;
+               if(i >= in)goto notc;
+       }
+       while(buf[i] != ')'){
+               if(buf[i++] == '\n')
+                       if(nl++ > 6)goto notc;
+               if(i >= in)goto notc;
+       }
+       while(buf[i] != '{'){
+               if(buf[i++] == '\n')
+                       if(nl++ > 6)goto notc;
+               if(i >= in)goto notc;
+       }
+       printf("c program text");
+       goto outa;
+notc:
+       i = 0;
+       while(buf[i] == 'c' || buf[i] == '#'){
+               while(buf[i++] != '\n')if(i >= in)goto notfort;
+       }
+       if(lookup(fort) == 1){
+               printf("fortran program text");
+               goto outa;
+       }
+notfort:
+       i=0;
+       if(ascom() == 0)goto notas;
+       j = i-1;
+       if(buf[i] == '.'){
+               i++;
+               if(lookup(as) == 1){
+                       printf("assembler program text"); 
+                       goto outa;
+               }
+               else if(buf[j] == '\n' && isalpha(buf[j+2])){
+                       printf("roff, nroff, or eqn input text");
+                       goto outa;
+               }
+       }
+       while(lookup(asc) == 0){
+               if(ascom() == 0)goto notas;
+               while(buf[i] != '\n' && buf[i++] != ':')
+                       if(i >= in)goto notas;
+               while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
+               j = i-1;
+               if(buf[i] == '.'){
+                       i++;
+                       if(lookup(as) == 1){
+                               printf("assembler program text"); 
+                               goto outa; 
+                       }
+                       else if(buf[j] == '\n' && isalpha(buf[j+2])){
+                               printf("roff, nroff, or eqn input text");
+                               goto outa;
+                       }
+               }
+       }
+       printf("assembler program text");
+       goto outa;
+notas:
+       for(i=0; i < in; i++)if(buf[i]&0200){
+               if (buf[0]=='\100' && buf[1]=='\357') {
+                       printf("troff output\n");
+                       goto out;
+               }
+               printf("data\n"); 
+               goto out; 
+       }
+       if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
+               printf("commands text");
+       else
+           if (english(buf, in))
+               printf("English text");
+       else
+           printf("ascii text");
+outa:
+       while(i < in)
+               if((buf[i++]&0377) > 127){
+                       printf(" with garbage\n");
+                       goto out;
+               }
+       /* if next few lines in then read whole file looking for nulls ...
+               while((in = read(ifile,buf,512)) > 0)
+                       for(i = 0; i < in; i++)
+                               if((buf[i]&0377) > 127){
+                                       printf(" with garbage\n");
+                                       goto out;
+                               }
+               /*.... */
+       printf("\n");
+out:;
+}
+lookup(tab)
+char *tab[];
+{
+       char r;
+       int k,j,l;
+       while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
+       for(j=0; tab[j] != 0; j++){
+               l=0;
+               for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
+               if(r == '\0')
+                       if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
+                           || buf[k] == '{' || buf[k] == '/'){
+                               i=k;
+                               return(1);
+                       }
+       }
+       return(0);
+}
+ccom(){
+       char cc;
+       while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
+       if(buf[i] == '/' && buf[i+1] == '*'){
+               i += 2;
+               while(buf[i] != '*' || buf[i+1] != '/'){
+                       if(buf[i] == '\\')i += 2;
+                       else i++;
+                       if(i >= in)return(0);
+               }
+               if((i += 2) >= in)return(0);
+       }
+       if(buf[i] == '\n')if(ccom() == 0)return(0);
+       return(1);
+}
+ascom(){
+       while(buf[i] == '/'){
+               i++;
+               while(buf[i++] != '\n')if(i >= in)return(0);
+               while(buf[i] == '\n')if(i++ >= in)return(0);
+       }
+       return(1);
+}
+
+english (bp, n)
+char *bp;
+{
+# define NASC 128
+       int ct[NASC], j, vow, freq, rare;
+       int badpun = 0, punct = 0;
+       if (n<50) return(0); /* no point in statistics on squibs */
+       for(j=0; j<NASC; j++)
+               ct[j]=0;
+       for(j=0; j<n; j++)
+       {
+               if (bp[j]<NASC)
+                       ct[bp[j]|040]++;
+               switch (bp[j])
+               {
+               case '.': 
+               case ',': 
+               case ')': 
+               case '%':
+               case ';': 
+               case ':': 
+               case '?':
+                       punct++;
+                       if ( j < n-1 &&
+                           bp[j+1] != ' ' &&
+                           bp[j+1] != '\n')
+                               badpun++;
+               }
+       }
+       if (badpun*5 > punct)
+               return(0);
+       vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u'];
+       freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n'];
+       rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z'];
+       if (2*ct[';'] > ct['e']) return(0);
+       if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */
+       return (vow*5 >= n-ct[' '] && freq >= 10*rare);
+}
diff --git a/usr/src/cmd/icheck.c b/usr/src/cmd/icheck.c
new file mode 100644 (file)
index 0000000..b488390
--- /dev/null
@@ -0,0 +1,475 @@
+#define        NI      16
+#define        NB      10
+#define        BITS    8
+#define        MAXFN   500
+
+#ifndef STANDALONE
+#include <stdio.h>
+#endif
+#include <sys/param.h>
+#include <sys/inode.h>
+#include <sys/ino.h>
+#include <sys/fblk.h>
+#include <sys/filsys.h>
+
+struct filsys  sblock;
+struct dinode  itab[INOPB*NI];
+daddr_t        iaddr[NADDR];
+daddr_t        blist[NB];
+char   *bmap;
+
+int    sflg;
+int    mflg;
+int    dflg;
+int    fi;
+ino_t  ino;
+
+ino_t  nrfile;
+ino_t  ndfile;
+ino_t  nbfile;
+ino_t  ncfile;
+
+daddr_t        ndirect;
+daddr_t        nindir;
+daddr_t        niindir;
+daddr_t        niiindir;
+daddr_t        nfree;
+daddr_t        ndup;
+
+int    nerror;
+
+long   atol();
+daddr_t        alloc();
+#ifndef STANDALONE
+char   *malloc();
+#endif
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       long n;
+
+       blist[0] = -1;
+#ifndef STANDALONE
+       while (--argc) {
+               argv++;
+               if (**argv=='-')
+               switch ((*argv)[1]) {
+               case 'd':
+                       dflg++;
+                       continue;
+
+
+               case 'm':
+                       mflg++;
+                       continue;
+
+               case 's':
+                       sflg++;
+                       continue;
+
+               case 'b':
+                       for(i=0; i<NB; i++) {
+                               n = atol(argv[1]);
+                               if(n == 0)
+                                       break;
+                               blist[i] = n;
+                               argv++;
+                               argc--;
+                       }
+                       blist[i] = -1;
+                       continue;
+
+               default:
+                       printf("Bad flag\n");
+               }
+               check(*argv);
+       }
+#else
+       {
+               static char fname[0];
+
+               printf("File: ");
+               gets(fname);
+               check(fname);
+       }
+#endif
+       return(nerror);
+}
+
+check(file)
+char *file;
+{
+       register i, j;
+       ino_t mino;
+       daddr_t d;
+       long n;
+
+       fi = open(file, sflg?2:0);
+       if (fi < 0) {
+               printf("cannot open %s\n", file);
+               nerror |= 04;
+               return;
+       }
+       printf("%s:\n", file);
+       nrfile = 0;
+       ndfile = 0;
+       ncfile = 0;
+       nbfile = 0;
+
+       ndirect = 0;
+       nindir = 0;
+       niindir = 0;
+       niiindir = 0;
+
+       ndup = 0;
+#ifndef STANDALONE
+       sync();
+#endif
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       mino = (sblock.s_isize-2) * INOPB;
+       ino = 0;
+       n = (sblock.s_fsize - sblock.s_isize + BITS-1) / BITS;
+       if (n != (unsigned)n) {
+               printf("Check fsize and isize: %ld, %u\n",
+                  sblock.s_fsize, sblock.s_isize);
+       }
+#ifdef STANDALONE
+       bmap = NULL;
+#else
+       bmap = malloc((unsigned)n);
+#endif
+       if (bmap==NULL) {
+               printf("Not enough core; duplicates unchecked\n");
+               dflg++;
+               sflg = 0;
+       }
+       if(!dflg)
+       for(i=0; i<(unsigned)n; i++)
+               bmap[i] = 0;
+       for(i=2;; i+=NI) {
+               if(ino >= mino)
+                       break;
+               bread((daddr_t)i, (char *)itab, sizeof(itab));
+               for(j=0; j<INOPB*NI; j++) {
+                       if(ino >= mino)
+                               break;
+                       ino++;
+                       pass1(&itab[j]);
+               }
+       }
+       ino = 0;
+#ifndef STANDALONE
+       sync();
+#endif
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       if (sflg) {
+               makefree();
+               close(fi);
+#ifndef STANDALONE
+               if (bmap)
+                       free(bmap);
+#endif
+               return;
+       }
+       nfree = 0;
+       while(n = alloc()) {
+               if (chk(n, "free"))
+                       break;
+               nfree++;
+       }
+       close(fi);
+#ifndef STANDALONE
+       if (bmap)
+               free(bmap);
+#endif
+
+       i = nrfile + ndfile + ncfile + nbfile;
+#ifndef STANDALONE
+       printf("files %6u (r=%u,d=%u,b=%u,c=%u)\n",
+               i, nrfile, ndfile, nbfile, ncfile);
+#else
+       printf("files %u (r=%u,d=%u,b=%u,c=%u)\n",
+               i, nrfile, ndfile, nbfile, ncfile);
+#endif
+       n = ndirect + nindir + niindir + niindir;
+#ifdef STANDALONE
+       printf("used %ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
+               n, nindir, niindir, niiindir, ndirect);
+       printf("free %ld\n", nfree);
+#else
+       printf("used %7ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
+               n, nindir, niindir, niiindir, ndirect);
+       printf("free %7ld\n", nfree);
+#endif
+       if(!dflg) {
+               n = 0;
+               for(d=sblock.s_isize; d<sblock.s_fsize; d++)
+                       if(!duped(d)) {
+                               if(mflg)
+                                       printf("%ld missing\n", d);
+                               n++;
+                       }
+               printf("missing%5ld\n", n);
+       }
+}
+
+pass1(ip)
+register struct dinode *ip;
+{
+       daddr_t ind1[NINDIR];
+       daddr_t ind2[NINDIR];
+       daddr_t ind3[NINDIR];
+       register i, j;
+       int k, l;
+
+       i = ip->di_mode & IFMT;
+       if(i == 0) {
+               sblock.s_tinode++;
+               return;
+       }
+       if(i == IFCHR) {
+               ncfile++;
+               return;
+       }
+       if(i == IFBLK) {
+               nbfile++;
+               return;
+       }
+       if(i == IFDIR)
+               ndfile++; else
+       if(i == IFREG)
+               nrfile++;
+       else {
+               printf("bad mode %u\n", ino);
+               return;
+       }
+       l3tol(iaddr, ip->di_addr, NADDR);
+       for(i=0; i<NADDR; i++) {
+               if(iaddr[i] == 0)
+                       continue;
+               if(i < NADDR-3) {
+                       ndirect++;
+                       chk(iaddr[i], "data (small)");
+                       continue;
+               }
+               nindir++;
+               if (chk(iaddr[i], "1st indirect"))
+                               continue;
+               bread(iaddr[i], (char *)ind1, BSIZE);
+               for(j=0; j<NINDIR; j++) {
+                       if(ind1[j] == 0)
+                               continue;
+                       if(i == NADDR-3) {
+                               ndirect++;
+                               chk(ind1[j], "data (large)");
+                               continue;
+                       }
+                       niindir++;
+                       if(chk(ind1[j], "2nd indirect"))
+                               continue;
+                       bread(ind1[j], (char *)ind2, BSIZE);
+                       for(k=0; k<NINDIR; k++) {
+                               if(ind2[k] == 0)
+                                       continue;
+                               if(i == NADDR-2) {
+                                       ndirect++;
+                                       chk(ind2[k], "data (huge)");
+                                       continue;
+                               }
+                               niiindir++;
+                               if(chk(ind2[k], "3rd indirect"))
+                                       continue;
+                               bread(ind2[k], (char *)ind3, BSIZE);
+                               for(l=0; l<NINDIR; l++)
+                                       if(ind3[l]) {
+                                               ndirect++;
+                                               chk(ind3[l], "data (garg)");
+                                       }
+                       }
+               }
+       }
+}
+
+chk(bno, s)
+daddr_t bno;
+char *s;
+{
+       register n;
+
+       if (bno<sblock.s_isize || bno>=sblock.s_fsize) {
+               printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
+               return(1);
+       }
+       if(duped(bno)) {
+               printf("%ld dup; inode=%u, class=%s\n", bno, ino, s);
+               ndup++;
+       }
+       for (n=0; blist[n] != -1; n++)
+               if (bno == blist[n])
+                       printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
+       return(0);
+}
+
+duped(bno)
+daddr_t bno;
+{
+       daddr_t d;
+       register m, n;
+
+       if(dflg)
+               return(0);
+       d = bno - sblock.s_isize;
+       m = 1 << (d%BITS);
+       n = (d/BITS);
+       if(bmap[n] & m)
+               return(1);
+       bmap[n] |= m;
+       return(0);
+}
+
+daddr_t
+alloc()
+{
+       int i;
+       daddr_t bno;
+       union {
+               char    data[BSIZE];
+               struct  fblk fb;
+       } buf;
+
+       sblock.s_tfree--;
+       if (sblock.s_nfree<=0)
+               return(0);
+       if (sblock.s_nfree>NICFREE) {
+               printf("Bad free list, s.b. count = %d\n", sblock.s_nfree);
+               return(0);
+       }
+       bno = sblock.s_free[--sblock.s_nfree];
+       sblock.s_free[sblock.s_nfree] = (daddr_t)0;
+       if(bno == 0)
+               return(bno);
+       if(sblock.s_nfree <= 0) {
+               bread(bno, buf.data, BSIZE);
+               sblock.s_nfree = buf.df_nfree;
+               if (sblock.s_nfree<0 || sblock.s_nfree>NICFREE) {
+                       printf("Bad free list, entry count of block %ld = %d\n",
+                               bno, sblock.s_nfree);
+                       sblock.s_nfree = 0;
+                       return(0);
+               }
+               for(i=0; i<NICFREE; i++)
+                       sblock.s_free[i] = buf.df_free[i];
+       }
+       return(bno);
+}
+
+bfree(bno)
+daddr_t bno;
+{
+       union {
+               char    data[BSIZE];
+               struct  fblk fb;
+       } buf;
+       int i;
+
+       sblock.s_tfree++;
+       if(sblock.s_nfree >= NICFREE) {
+               for(i=0; i<BSIZE; i++)
+                       buf.data[i] = 0;
+               buf.df_nfree = sblock.s_nfree;
+               for(i=0; i<NICFREE; i++)
+                       buf.df_free[i] = sblock.s_free[i];
+               bwrite(bno, buf.data);
+               sblock.s_nfree = 0;
+       }
+       sblock.s_free[sblock.s_nfree] = bno;
+       sblock.s_nfree++;
+}
+
+bread(bno, buf, cnt)
+daddr_t bno;
+char *buf;
+{
+       register i;
+
+       lseek(fi, bno*BSIZE, 0);
+       if (read(fi, buf, cnt) != cnt) {
+               printf("read error %ld\n", bno);
+               if (sflg) {
+                       printf("No update\n");
+                       sflg = 0;
+               }
+               for(i=0; i<BSIZE; i++)
+                       buf[i] = 0;
+       }
+}
+
+bwrite(bno, buf)
+daddr_t bno;
+char   *buf;
+{
+
+       lseek(fi, bno*BSIZE, 0);
+       if (write(fi, buf, BSIZE) != BSIZE)
+               printf("write error %ld\n", bno);
+}
+
+makefree()
+{
+       char flg[MAXFN];
+       int adr[MAXFN];
+       register i, j;
+       daddr_t f, d;
+       int m, n;
+
+       n = sblock.s_n;
+       if(n <= 0 || n > MAXFN)
+               n = MAXFN;
+       sblock.s_n = n;
+       m = sblock.s_m;
+       if(m <= 0 || m > sblock.s_n)
+               m = 3;
+       sblock.s_m = m;
+
+       for(i=0; i<n; i++)
+               flg[i] = 0;
+       i = 0;
+       for(j=0; j<n; j++) {
+               while(flg[i])
+                       i = (i+1)%n;
+               adr[j] = i+1;
+               flg[i]++;
+               i = (i+m)%n;
+       }
+
+       sblock.s_nfree = 0;
+       sblock.s_ninode = 0;
+       sblock.s_flock = 0;
+       sblock.s_ilock = 0;
+       sblock.s_fmod = 0;
+       sblock.s_ronly = 0;
+#ifndef STANDALONE
+       time(&sblock.s_time);
+#endif
+       sblock.s_tfree = 0;
+       sblock.s_tinode = 0;
+
+       bfree((daddr_t)0);
+       d = sblock.s_fsize-1;
+       while(d%sblock.s_n)
+               d++;
+       for(; d > 0; d -= sblock.s_n)
+       for(i=0; i<sblock.s_n; i++) {
+               f = d - adr[i];
+               if(f < sblock.s_fsize && f >= sblock.s_isize)
+                       if(!duped(f))
+                               bfree(f);
+       }
+       bwrite((daddr_t)1, (char *)&sblock);
+#ifndef STANDALONE
+       sync();
+#endif
+       return;
+}
diff --git a/usr/src/cmd/iostat.c b/usr/src/cmd/iostat.c
new file mode 100644 (file)
index 0000000..8e03f88
--- /dev/null
@@ -0,0 +1,271 @@
+int    bflg;
+int    dflg;
+int    tflg;
+int    iflg;
+int    aflg;
+int    sflg;
+struct
+{
+       char    name[8];
+       int     type;
+       unsigned        value;
+} nl[] = {
+       "_dk_busy", 0, 0,
+       "_io_info", 0, 0,
+       "\0\0\0\0\0\0\0\0", 0, 0
+};
+struct
+{
+       int     busy;
+       long    etime[32];
+       long    numb[3];
+       long    wds[3];
+       long    tin;
+       long    tout;
+} s, s1;
+
+struct iostat {
+       int     nbuf;
+       long    nread;
+       long    nreada;
+       long    ncache;
+       long    nwrite;
+       long    bufcount[50];
+} io_info, io_delta;
+double etime;
+
+int    mf;
+
+main(argc, argv)
+char *argv[];
+{
+       extern char *ctime();
+       register  i;
+       int iter;
+       double f1, f2;
+       long t;
+
+       nlist("/unix", nl);
+       if(nl[0].type == -1) {
+               printf("dk_busy not found in /unix namelist\n");
+               exit(1);
+       }
+       mf = open("/dev/kmem", 0);
+       if(mf < 0) {
+               printf("cannot open /dev/kmem\n");
+               exit(1);
+       }
+       iter = 0;
+       while (argc>1&&argv[1][0]=='-') {
+               if (argv[1][1]=='d')
+                       dflg++;
+               else if (argv[1][1]=='s')
+                       sflg++;
+               else if (argv[1][1]=='a')
+                       aflg++;
+               else if (argv[1][1]=='t')
+                       tflg++;
+               else if (argv[1][1]=='i')
+                       iflg++;
+               else if (argv[1][1]=='b')
+                       bflg++;
+               argc--;
+               argv++;
+       }
+       if(argc > 2)
+               iter = atoi(argv[2]);
+       if (!(sflg|iflg)) {
+       if(tflg)
+               printf("         TTY");
+       if (bflg==0)
+       printf("   RF                RK                RP                  PERCENT\n");
+       if(tflg)
+               printf("   tin  tout");
+       if (bflg==0)
+       printf("   tpm  msps  mspt   tpm  msps  mspt   tpm  msps  mspt  user  nice systm  idle\n");
+       }
+
+loop:
+       lseek(mf, (long)nl[0].value, 0);
+       read(mf, (char *)&s, sizeof s);
+       for(i=0; i<40; i++) {
+               t = s.etime[i];
+               s.etime[i] -= s1.etime[i];
+               s1.etime[i] = t;
+       }
+       t = 0;
+       for(i=0; i<32; i++)
+               t += s.etime[i];
+       etime = t;
+       if(etime == 0.)
+               etime = 1.;
+       if (bflg) {
+               biostats();
+               goto contin;
+       }
+       if (dflg) {
+               long tm;
+               time(&tm);
+               printf("%s", ctime(&tm));
+       }
+       if (aflg)
+               printf("%.2f minutes total\n", etime/3600);
+       if (sflg) {
+               stats2(etime);
+               goto contin;
+       }
+       if (iflg) {
+               stats3(etime);
+               goto contin;
+       }
+       etime /= 60.;
+       if(tflg) {
+               f1 = s.tin;
+               f2 = s.tout;
+               printf("%6.1f", f1/etime);
+               printf("%6.1f", f2/etime);
+       }
+       for(i=0; i<3; i++)
+               stats(i);
+       for(i=0; i<4; i++)
+               stat1(i*8);
+       printf("\n");
+contin:
+       --iter;
+       if(iter)
+       if(argc > 1) {
+               sleep(atoi(argv[1]));
+               goto loop;
+       }
+}
+
+/* usec per word for the various disks */
+double xf[] = {
+       16.0,   /* RF */
+       11.1,   /* RK03/05 */
+       2.48,   /* RP06 */
+};
+
+stats(dn)
+{
+       register i;
+       double f1, f2, f3;
+       double f4, f5, f6;
+       long t;
+
+       t = 0;
+       for(i=0; i<32; i++)
+               if(i & (1<<dn))
+                       t += s.etime[i];
+       f1 = t;
+       f1 = f1/60.;
+       f2 = s.numb[dn];
+       if(f2 == 0.) {
+               printf("%6.0f%6.1f%6.1f", 0.0, 0.0, 0.0);
+               return;
+       }
+       f3 = s.wds[dn];
+       f3 = f3*32.;
+       f4 = xf[dn];
+       f4 = f4*1.0e-6;
+       f5 = f1 - f4*f3;
+       f6 = f1 - f5;
+       printf("%6.0f", f2*60./etime);
+       printf("%6.1f", f5*1000./f2);
+       printf("%6.1f", f6*1000./f2);
+}
+
+stat1(o)
+{
+       register i;
+       long t;
+       double f1, f2;
+
+       t = 0;
+       for(i=0; i<32; i++)
+               t += s.etime[i];
+       f1 = t;
+       if(f1 == 0.)
+               f1 = 1.;
+       t = 0;
+       for(i=0; i<8; i++)
+               t += s.etime[o+i];
+       f2 = t;
+       printf("%6.2f", f2*100./f1);
+}
+
+stats2(t)
+double t;
+{
+       register i, j;
+
+       for (i=0; i<4; i++) {
+               for (j=0; j<8; j++)
+                       printf("%6.2f\n", s.etime[8*i+j]/(t/100));
+               printf("\n");
+       }
+}
+
+stats3(t)
+double t;
+{
+       register i;
+       double sum;
+
+       t /= 100;
+       printf("%6.2f idle\n", s.etime[24]/t);
+       sum = 0;
+       for (i=0; i<8; i++)
+               sum += s.etime[i];
+       printf("%6.2f user\n", sum/t);
+       sum = 0;
+       for (i=0; i<8; i++)
+               sum += s.etime[8+i];
+       printf("%6.2f nice\n", sum/t);
+       sum = 0;
+       for (i=0; i<8; i++)
+               sum += s.etime[16+i];
+       printf("%6.2f system\n", sum/t);
+       sum = 0;
+       for (i=1; i<8; i++)
+               sum += s.etime[24+i];
+       printf("%6.2f IO wait\n", sum/t);
+       sum = 0;
+       for (i=1; i<8; i++)
+               sum += s.etime[i]+s.etime[i+8]+s.etime[i+16]+s.etime[i+24];
+       printf("%6.2f IO active\n", sum/t);
+       sum = 0;
+       for (i=0; i<32; i++)
+               if (i&01)
+                       sum += s.etime[i];
+       printf("%6.2f RF active\n", sum/t);
+       sum = 0;
+       for (i=0; i<32; i++)
+               if (i&02)
+                       sum += s.etime[i];
+       printf("%6.2f RK active\n", sum/t);
+       sum = 0;
+       for (i=0; i<32; i++)
+               if (i&04)
+                       sum += s.etime[i];
+       printf("%6.2f RP active\n", sum/t);
+}
+
+biostats()
+{
+register i;
+
+       lseek(mf,(long)nl[1].value, 0);
+       read(mf, (char *)&io_info, sizeof(io_info));
+       printf("%D\t%D\t%D\t%D\n",
+        io_info.nread-io_delta.nread, io_info.nreada-io_delta.nreada,
+        io_info.ncache-io_delta.ncache, io_info.nwrite-io_delta.nwrite);
+
+       for(i=0; i<30; ) {
+               printf("%D\t",(long)io_info.bufcount[i]-io_delta.bufcount[i]);
+               i++;
+               if (i % 10 == 0)
+                       printf("\n");
+       }
+       io_delta = io_info;
+}
diff --git a/usr/src/cmd/kill.c b/usr/src/cmd/kill.c
new file mode 100644 (file)
index 0000000..e56f0f0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * kill - send signal to process
+ */
+
+#include <signal.h>
+
+main(argc, argv)
+char **argv;
+{
+       register signo, pid, res;
+       int errlev;
+       extern char *sys_errlist[];
+       extern errno;
+
+       errlev = 0;
+       if (argc <= 1) {
+       usage:
+               printf("usage: kill [ -signo ] pid ...\n");
+               exit(2);
+       }
+       if (*argv[1] == '-') {
+               signo = atoi(argv[1]+1);
+               argc--;
+               argv++;
+       } else
+               signo = SIGTERM;
+       argv++;
+       while (argc > 1) {
+               if (**argv<'0' || **argv>'9')
+                       goto usage;
+               res = kill(pid = atoi(*argv), signo);
+               if (res<0) {
+                       printf("%u: %s\n", pid, sys_errlist[errno]);
+                       errlev = 1;
+               }
+               argc--;
+               argv++;
+       }
+       return(errlev);
+}