BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Mon, 12 Feb 1979 13:50:21 +0000 (05:50 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Mon, 12 Feb 1979 13:50:21 +0000 (05:50 -0800)
Work on file usr/src/cmd/accton.c
Work on file usr/src/cmd/cat.c
Work on file usr/src/cmd/checkeq.c
Work on file usr/src/games/arithmetic.c
Work on file usr/src/cmd/bc.y
Work on file usr/src/cmd/basename.c
Work on file usr/src/cmd/call.c
Work on file usr/src/cmd/cal.c
Work on file usr/src/cmd/cb.c
Work on file usr/src/games/bcd.c
Work on file usr/src/cmd/comm.c
Work on file usr/src/cmd/chmod.c
Work on file usr/src/cmd/col.c
Work on file usr/src/cmd/chown.c
Work on file usr/src/cmd/chgrp.c
Work on file usr/src/cmd/cmp.c
Work on file usr/src/cmd/date.c
Work on file usr/src/cmd/crypt.c
Work on file usr/src/cmd/dd.c
Work on file usr/src/cmd/cron.c
Work on file usr/src/cmd/diffh.c
Work on file usr/src/cmd/false.sh
Work on file usr/src/cmd/egrep.y
Work on file usr/src/cmd/expr.y
Work on file usr/src/cmd/ed/ed.c
Work on file usr/src/cmd/echo.c
Work on file usr/src/cmd/kill.c
Work on file usr/src/cmd/join.c
Work on file usr/src/cmd/makekey.c
Work on file usr/src/cmd/lookbib.sh
Work on file usr/src/cmd/man/man.sh
Work on file usr/src/cmd/lorder.sh
Work on file usr/src/cmd/ln.c
Work on file usr/src/cmd/ls/ls.c
Work on file usr/src/cmd/look.c
Work on file usr/src/cmd/mkdir.c
Work on file usr/src/cmd/ncheck.c
Work on file usr/src/cmd/nice.c
Work on file usr/src/cmd/nohup.sh
Work on file usr/src/cmd/mknod.c
Work on file usr/src/cmd/mv.c
Work on file usr/src/cmd/mount.c
Work on file usr/src/cmd/pr.c
Work on file usr/src/games/number.c
Work on file usr/src/cmd/od.c
Work on file usr/src/cmd/rev.c
Work on file usr/src/cmd/rm.c
Work on file usr/src/cmd/sort.c
Work on file usr/src/cmd/rmdir.c
Work on file usr/src/cmd/spline.c
Work on file usr/src/cmd/split.c
Work on file usr/src/cmd/sleep.c
Work on file usr/src/cmd/tc.c
Work on file usr/src/cmd/sync.c
Work on file usr/src/cmd/sum.c
Work on file usr/src/cmd/tty.c
Work on file usr/src/cmd/tr.c
Work on file usr/src/cmd/tsort.c
Work on file usr/src/cmd/touch.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
Work on file usr/src/cmd/true.sh
Work on file usr/src/cmd/umount.c
Work on file usr/src/cmd/update.c
Work on file usr/src/cmd/wc.c
Work on file usr/src/cmd/units.c
Work on file usr/src/cmd/uniq.c
Work on file usr/src/cmd/who.c

Synthesized-from: 3bsd

69 files changed:
usr/src/cmd/accton.c [new file with mode: 0644]
usr/src/cmd/basename.c [new file with mode: 0644]
usr/src/cmd/bc.y [new file with mode: 0644]
usr/src/cmd/cal.c [new file with mode: 0644]
usr/src/cmd/call.c [new file with mode: 0644]
usr/src/cmd/cat.c [new file with mode: 0644]
usr/src/cmd/cb.c [new file with mode: 0644]
usr/src/cmd/checkeq.c [new file with mode: 0644]
usr/src/cmd/chgrp.c [new file with mode: 0644]
usr/src/cmd/chmod.c [new file with mode: 0644]
usr/src/cmd/chown.c [new file with mode: 0644]
usr/src/cmd/cmp.c [new file with mode: 0644]
usr/src/cmd/col.c [new file with mode: 0644]
usr/src/cmd/comm.c [new file with mode: 0644]
usr/src/cmd/cron.c [new file with mode: 0644]
usr/src/cmd/crypt.c [new file with mode: 0644]
usr/src/cmd/date.c [new file with mode: 0644]
usr/src/cmd/dd.c [new file with mode: 0644]
usr/src/cmd/diffh.c [new file with mode: 0644]
usr/src/cmd/echo.c [new file with mode: 0644]
usr/src/cmd/ed/ed.c [new file with mode: 0644]
usr/src/cmd/egrep.y [new file with mode: 0644]
usr/src/cmd/expr.y [new file with mode: 0644]
usr/src/cmd/false.sh [new file with mode: 0755]
usr/src/cmd/join.c [new file with mode: 0644]
usr/src/cmd/kill.c [new file with mode: 0644]
usr/src/cmd/ln.c [new file with mode: 0644]
usr/src/cmd/look.c [new file with mode: 0644]
usr/src/cmd/lookbib.sh [new file with mode: 0755]
usr/src/cmd/lorder.sh [new file with mode: 0755]
usr/src/cmd/ls/ls.c [new file with mode: 0644]
usr/src/cmd/makekey.c [new file with mode: 0644]
usr/src/cmd/man/man.sh [new file with mode: 0755]
usr/src/cmd/mkdir.c [new file with mode: 0644]
usr/src/cmd/mknod.c [new file with mode: 0644]
usr/src/cmd/mount.c [new file with mode: 0644]
usr/src/cmd/mv.c [new file with mode: 0644]
usr/src/cmd/ncheck.c [new file with mode: 0644]
usr/src/cmd/nice.c [new file with mode: 0644]
usr/src/cmd/nohup.sh [new file with mode: 0755]
usr/src/cmd/od.c [new file with mode: 0644]
usr/src/cmd/pr.c [new file with mode: 0644]
usr/src/cmd/rev.c [new file with mode: 0644]
usr/src/cmd/rm.c [new file with mode: 0644]
usr/src/cmd/rmdir.c [new file with mode: 0644]
usr/src/cmd/sleep.c [new file with mode: 0644]
usr/src/cmd/sort.c [new file with mode: 0644]
usr/src/cmd/spline.c [new file with mode: 0644]
usr/src/cmd/split.c [new file with mode: 0644]
usr/src/cmd/sum.c [new file with mode: 0644]
usr/src/cmd/sync.c [new file with mode: 0644]
usr/src/cmd/tc.c [new file with mode: 0644]
usr/src/cmd/test.c [new file with mode: 0644]
usr/src/cmd/time.c [new file with mode: 0644]
usr/src/cmd/tk.c [new file with mode: 0644]
usr/src/cmd/touch.c [new file with mode: 0644]
usr/src/cmd/tr.c [new file with mode: 0644]
usr/src/cmd/true.sh [new file with mode: 0755]
usr/src/cmd/tsort.c [new file with mode: 0644]
usr/src/cmd/tty.c [new file with mode: 0644]
usr/src/cmd/umount.c [new file with mode: 0644]
usr/src/cmd/uniq.c [new file with mode: 0644]
usr/src/cmd/units.c [new file with mode: 0644]
usr/src/cmd/update.c [new file with mode: 0644]
usr/src/cmd/wc.c [new file with mode: 0644]
usr/src/cmd/who.c [new file with mode: 0644]
usr/src/games/arithmetic.c [new file with mode: 0644]
usr/src/games/bcd.c [new file with mode: 0644]
usr/src/games/number.c [new file with mode: 0644]

diff --git a/usr/src/cmd/accton.c b/usr/src/cmd/accton.c
new file mode 100644 (file)
index 0000000..90f1e9f
--- /dev/null
@@ -0,0 +1,14 @@
+main(argc, argv)
+char **argv;
+{
+       extern errno;
+       if (argc > 1)
+               acct(argv[1]);
+       else
+               acct((char *)0);
+       if (errno) {
+               perror("accton");
+               exit(1);
+       }
+       exit(0);
+}
diff --git a/usr/src/cmd/basename.c b/usr/src/cmd/basename.c
new file mode 100644 (file)
index 0000000..52df45f
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "stdio.h"
+
+main(argc, argv)
+char **argv;
+{
+       register char *p1, *p2, *p3;
+
+       if (argc < 2) {
+               putchar('\n');
+               exit(1);
+       }
+       p1 = argv[1];
+       p2 = p1;
+       while (*p1) {
+               if (*p1++ == '/')
+                       p2 = p1;
+       }
+       if (argc>2) {
+               for(p3=argv[2]; *p3; p3++) 
+                       ;
+               while(p1>p2 && p3>argv[2])
+                       if(*--p3 != *--p1)
+                               goto output;
+               *p1 = '\0';
+       }
+output:
+       puts(p2, stdout);
+       exit(0);
+}
diff --git a/usr/src/cmd/bc.y b/usr/src/cmd/bc.y
new file mode 100644 (file)
index 0000000..1e50fc5
--- /dev/null
@@ -0,0 +1,597 @@
+%{
+       int *getout();
+%}
+%right '='
+%left '+' '-'
+%left '*' '/' '%'
+%right '^'
+%left UMINUS
+
+%term LETTER DIGIT SQRT LENGTH _IF  FFF EQ
+%term _WHILE _FOR NE LE GE INCR DECR
+%term _RETURN _BREAK _DEFINE BASE OBASE SCALE
+%term EQPL EQMI EQMUL EQDIV EQREM EQEXP
+%term _AUTO DOT
+%term QSTR
+
+%{
+#include <stdio.h>
+int in;
+char cary[1000], *cp = { cary };
+char string[1000], *str = {string};
+int crs = '0';
+int rcrs = '0';  /* reset crs */
+int bindx = 0;
+int lev = 0;
+int ln;
+char *ss;
+int bstack[10] = { 0 };
+char *numb[15] = {
+  " 0", " 1", " 2", " 3", " 4", " 5",
+  " 6", " 7", " 8", " 9", " 10", " 11",
+  " 12", " 13", " 14" };
+int *pre, *post;
+%}
+%%
+start  : 
+       |  start stat tail
+               = output( $2 );
+       |  start def dargs ')' '{' dlist slist '}'
+               ={      bundle( 6,pre, $7, post ,"0",numb[lev],"Q");
+                       conout( $$, $2 );
+                       rcrs = crs;
+                       output( "" );
+                       lev = bindx = 0;
+                       }
+       ;
+
+dlist  :  tail
+       | dlist _AUTO dlets tail
+       ;
+
+stat   :  e 
+               ={ bundle(2, $1, "ps." ); }
+       | 
+               ={ bundle(1, "" ); }
+       |  QSTR
+               ={ bundle(3,"[",$1,"]P");}
+       |  LETTER '=' e
+               ={ bundle(3, $3, "s", $1 ); }
+       |  LETTER '[' e ']' '=' e
+               ={ bundle(4, $6, $3, ":", geta($1)); }
+       |  LETTER EQOP e
+               ={ bundle(6, "l", $1, $3, $2, "s", $1 ); }
+       |  LETTER '[' e ']' EQOP e
+               ={ bundle(8,$3, ";", geta($1), $6, $5, $3, ":", geta($1));}
+       |  _BREAK
+               ={ bundle(2, numb[lev-bstack[bindx-1]], "Q" ); }
+       |  _RETURN '(' e ')'
+               = bundle(4, $3, post, numb[lev], "Q" );
+       |  _RETURN '(' ')'
+               = bundle(4, "0", post, numb[lev], "Q" );
+       | _RETURN
+               = bundle(4,"0",post,numb[lev],"Q");
+       | SCALE '=' e
+               = bundle(2, $3, "k");
+       | SCALE EQOP e
+               = bundle(4,"K",$3,$2,"k");
+       | BASE '=' e
+               = bundle(2,$3, "i");
+       | BASE EQOP e
+               = bundle(4,"I",$3,$2,"i");
+       | OBASE '=' e
+               = bundle(2,$3,"o");
+       | OBASE EQOP e
+               = bundle(4,"O",$3,$2,"o");
+       |  '{' slist '}'
+               ={ $$ = $2; }
+       |  FFF
+               ={ bundle(1,"fY"); }
+       |  error
+               ={ bundle(1,"c"); }
+       |  _IF CRS BLEV '(' re ')' stat
+               ={      conout( $7, $2 );
+                       bundle(3, $5, $2, " " );
+                       }
+       |  _WHILE CRS '(' re ')' stat BLEV
+               ={      bundle(3, $6, $4, $2 );
+                       conout( $$, $2 );
+                       bundle(3, $4, $2, " " );
+                       }
+       |  fprefix CRS re ';' e ')' stat BLEV
+               ={      bundle(5, $7, $5, "s.", $3, $2 );
+                       conout( $$, $2 );
+                       bundle(5, $1, "s.", $3, $2, " " );
+                       }
+       |  '~' LETTER '=' e
+               ={      bundle(3,$4,"S",$2); }
+       ;
+
+EQOP   :  EQPL
+               ={ $$ = "+"; }
+       |  EQMI
+               ={ $$ = "-"; }
+       |  EQMUL
+               ={ $$ = "*"; }
+       |  EQDIV
+               ={ $$ = "/"; }
+       |  EQREM
+               ={ $$ = "%%"; }
+       |  EQEXP
+               ={ $$ = "^"; }
+       ;
+
+fprefix        :  _FOR '(' e ';'
+               ={ $$ = $3; }
+       ;
+
+BLEV   :
+               ={ --bindx; }
+       ;
+
+slist  :  stat
+       |  slist tail stat
+               ={ bundle(2, $1, $3 ); }
+       ;
+
+tail   :  '\n'
+               ={ln++;}
+       |  ';'
+       ;
+
+re     :  e EQ e
+               = bundle(3, $1, $3, "=" );
+       |  e '<' e
+               = bundle(3, $1, $3, ">" );
+       |  e '>' e
+               = bundle(3, $1, $3, "<" );
+       |  e NE e
+               = bundle(3, $1, $3, "!=" );
+       |  e GE e
+               = bundle(3, $1, $3, "!>" );
+       |  e LE e
+               = bundle(3, $1, $3, "!<" );
+       |  e
+               = bundle(2, $1, " 0!=" );
+       ;
+
+e      :  e '+' e
+               = bundle(3, $1, $3, "+" );
+       |  e '-' e
+               = bundle(3, $1, $3, "-" );
+       | '-' e         %prec UMINUS
+               = bundle(3, " 0", $2, "-" );
+       |  e '*' e
+               = bundle(3, $1, $3, "*" );
+       |  e '/' e
+               = bundle(3, $1, $3, "/" );
+       |  e '%' e
+               = bundle(3, $1, $3, "%%" );
+       |  e '^' e
+               = bundle(3, $1, $3, "^" );
+       |  LETTER '[' e ']'
+               ={ bundle(3,$3, ";", geta($1)); }
+       |  LETTER INCR
+               = bundle(4, "l", $1, "d1+s", $1 );
+       |  INCR LETTER
+               = bundle(4, "l", $2, "1+ds", $2 );
+       |  DECR LETTER
+               = bundle(4, "l", $2, "1-ds", $2 );
+       |  LETTER DECR
+               = bundle(4, "l", $1, "d1-s", $1 );
+       | LETTER '[' e ']' INCR
+               = bundle(7,$3,";",geta($1),"d1+",$3,":",geta($1));
+       | INCR LETTER '[' e ']'
+               = bundle(7,$4,";",geta($2),"1+d",$4,":",geta($2));
+       | LETTER '[' e ']' DECR
+               = bundle(7,$3,";",geta($1),"d1-",$3,":",geta($1));
+       | DECR LETTER '[' e ']'
+               = bundle(7,$4,";",geta($2),"1-d",$4,":",geta($2));
+       | SCALE INCR
+               = bundle(1,"Kd1+k");
+       | INCR SCALE
+               = bundle(1,"K1+dk");
+       | SCALE DECR
+               = bundle(1,"Kd1-k");
+       | DECR SCALE
+               = bundle(1,"K1-dk");
+       | BASE INCR
+               = bundle(1,"Id1+i");
+       | INCR BASE
+               = bundle(1,"I1+di");
+       | BASE DECR
+               = bundle(1,"Id1-i");
+       | DECR BASE
+               = bundle(1,"I1-di");
+       | OBASE INCR
+               = bundle(1,"Od1+o");
+       | INCR OBASE
+               = bundle(1,"O1+do");
+       | OBASE DECR
+               = bundle(1,"Od1-o");
+       | DECR OBASE
+               = bundle(1,"O1-do");
+       |  LETTER '(' cargs ')'
+               = bundle(4, $3, "l", getf($1), "x" );
+       |  LETTER '(' ')'
+               = bundle(3, "l", getf($1), "x" );
+       |  cons
+               ={ bundle(2, " ", $1 ); }
+       |  DOT cons
+               ={ bundle(2, " .", $2 ); }
+       |  cons DOT cons
+               ={ bundle(4, " ", $1, ".", $3 ); }
+       |  cons DOT
+               ={ bundle(3, " ", $1, "." ); }
+       |  DOT
+               ={ $$ = "l."; }
+       |  LETTER
+               = { bundle(2, "l", $1 ); }
+       |  LETTER '=' e
+               ={ bundle(3, $3, "ds", $1 ); }
+       |  LETTER EQOP e        %prec '='
+               ={ bundle(6, "l", $1, $3, $2, "ds", $1 ); }
+       | LETTER '[' e ']' '=' e
+               = { bundle(5,$6,"d",$3,":",geta($1)); }
+       | LETTER '[' e ']' EQOP e
+               = { bundle(9,$3,";",geta($1),$6,$5,"d",$3,":",geta($1)); }
+       | LENGTH '(' e ')'
+               = bundle(2,$3,"Z");
+       | SCALE '(' e ')'
+               = bundle(2,$3,"X");     /* must be before '(' e ')' */
+       |  '(' e ')'
+               = { $$ = $2; }
+       |  '?'
+               ={ bundle(1, "?" ); }
+       |  SQRT '(' e ')'
+               ={ bundle(2, $3, "v" ); }
+       | '~' LETTER
+               ={ bundle(2,"L",$2); }
+       | SCALE '=' e
+               = bundle(2,$3,"dk");
+       | SCALE EQOP e          %prec '='
+               = bundle(4,"K",$3,$2,"dk");
+       | BASE '=' e
+               = bundle(2,$3,"di");
+       | BASE EQOP e           %prec '='
+               = bundle(4,"I",$3,$2,"di");
+       | OBASE '=' e
+               = bundle(2,$3,"do");
+       | OBASE EQOP e          %prec '='
+               = bundle(4,"O",$3,$2,"do");
+       | SCALE
+               = bundle(1,"K");
+       | BASE
+               = bundle(1,"I");
+       | OBASE
+               = bundle(1,"O");
+       ;
+
+cargs  :  eora
+       |  cargs ',' eora
+               = bundle(2, $1, $3 );
+       ;
+eora:    e
+       | LETTER '[' ']'
+               =bundle(2,"l",geta($1));
+       ;
+
+cons   :  constant
+               ={ *cp++ = '\0'; }
+
+constant:
+         '_'
+               ={ $$ = cp; *cp++ = '_'; }
+       |  DIGIT
+               ={ $$ = cp; *cp++ = $1; }
+       |  constant DIGIT
+               ={ *cp++ = $2; }
+       ;
+
+CRS    :
+               ={ $$ = cp; *cp++ = crs++; *cp++ = '\0';
+                       if(crs == '[')crs+=3;
+                       if(crs == 'a')crs='{';
+                       if(crs >= 0241){yyerror("program too big");
+                               getout();
+                       }
+                       bstack[bindx++] = lev++; }
+       ;
+
+def    :  _DEFINE LETTER '('
+               ={      $$ = getf($2);
+                       pre = "";
+                       post = "";
+                       lev = 1;
+                       bstack[bindx=0] = 0;
+                       }
+       ;
+
+dargs  :
+       |  lora
+               ={ pp( $1 ); }
+       |  dargs ',' lora
+               ={ pp( $3 ); }
+       ;
+
+dlets  :  lora
+               ={ tp($1); }
+       |  dlets ',' lora
+               ={ tp($3); }
+       ;
+lora   :  LETTER
+       |  LETTER '[' ']'
+               ={ $$ = geta($1); }
+       ;
+
+%%
+# define error 256
+
+int peekc = -1;
+int sargc;
+int ifile;
+char **sargv;
+
+char funtab[52] = {
+       01,0,02,0,03,0,04,0,05,0,06,0,07,0,010,0,011,0,012,0,013,0,014,0,015,0,016,0,017,0,
+       020,0,021,0,022,0,023,0,024,0,025,0,026,0,027,0,030,0,031,0,032,0 };
+char atab[52] = {
+       0241,0,0242,0,0243,0,0244,0,0245,0,0246,0,0247,0,0250,0,0251,0,0252,0,0253,0,
+       0254,0,0255,0,0256,0,0257,0,0260,0,0261,0,0262,0,0263,0,0264,0,0265,0,0266,0,
+       0267,0,0270,0,0271,0,0272,0};
+char *letr[26] = {
+  "a","b","c","d","e","f","g","h","i","j",
+  "k","l","m","n","o","p","q","r","s","t",
+  "u","v","w","x","y","z" } ;
+char *dot = { "." };
+yylex(){
+       int c, ch;
+restart:
+       c = getch();
+       peekc = -1;
+       while( c == ' ' || c == '\t' ) c = getch();
+       if(c == '\\'){
+               getch();
+               goto restart;
+       }
+       if( c<= 'z' && c >= 'a' ) {
+               /* look ahead to look for reserved words */
+               peekc = getch();
+               if( peekc >= 'a' && peekc <= 'z' ){ /* must be reserved word */
+                       if( c=='i' && peekc=='f' ){ c=_IF; goto skip; }
+                       if( c=='w' && peekc=='h' ){ c=_WHILE; goto skip; }
+                       if( c=='f' && peekc=='o' ){ c=_FOR; goto skip; }
+                       if( c=='s' && peekc=='q' ){ c=SQRT; goto skip; }
+                       if( c=='r' && peekc=='e' ){ c=_RETURN; goto skip; }
+                       if( c=='b' && peekc=='r' ){ c=_BREAK; goto skip; }
+                       if( c=='d' && peekc=='e' ){ c=_DEFINE; goto skip; }
+                       if( c=='s' && peekc=='c' ){ c= SCALE; goto skip; }
+                       if( c=='b' && peekc=='a' ){ c=BASE; goto skip; }
+                       if( c=='i' && peekc == 'b'){ c=BASE; goto skip; }
+                       if( c=='o' && peekc=='b' ){ c=OBASE; goto skip; }
+                       if( c=='d' && peekc=='i' ){ c=FFF; goto skip; }
+                       if( c=='a' && peekc=='u' ){ c=_AUTO; goto skip; }
+                       if( c == 'l' && peekc=='e'){ c=LENGTH; goto skip; }
+                       if( c == 'q' && peekc == 'u'){getout();}
+                       /* could not be found */
+                       return( error );
+               skip:   /* skip over rest of word */
+                       peekc = -1;
+                       while( (ch = getch()) >= 'a' && ch <= 'z' );
+                       peekc = ch;
+                       return( c );
+               }
+
+               /* usual case; just one single letter */
+
+               yylval = letr[c-'a'];
+               return( LETTER );
+       }
+       if( c>= '0' && c <= '9' || c>= 'A' && c<= 'F' ){
+               yylval = c;
+               return( DIGIT );
+       }
+       switch( c ){
+       case '.':       return( DOT );
+       case '=':
+               switch( peekc = getch() ){
+               case '=': c=EQ; goto gotit;
+               case '+': c=EQPL; goto gotit;
+               case '-': c=EQMI; goto gotit;
+               case '*': c=EQMUL; goto gotit;
+               case '/': c=EQDIV; goto gotit;
+               case '%': c=EQREM; goto gotit;
+               case '^': c=EQEXP; goto gotit;
+               default:   return( '=' );
+                         gotit:     peekc = -1; return(c);
+                 }
+       case '+':       return( cpeek( '+', INCR, '+' ) );
+       case '-':       return( cpeek( '-', DECR, '-' ) );
+       case '<':       return( cpeek( '=', LE, '<' ) );
+       case '>':       return( cpeek( '=', GE, '>' ) );
+       case '!':       return( cpeek( '=', NE, '!' ) );
+       case '/':
+               if((peekc = getch()) == '*'){
+                       peekc = -1;
+                       while((getch() != '*') || ((peekc = getch()) != '/'));
+                       peekc = -1;
+                       goto restart;
+               }
+               else return(c);
+       case '"':       
+                yylval = str;
+                while((c=getch()) != '"'){*str++ = c;
+                       if(str >= &string[999]){yyerror("string space exceeded");
+                       getout();
+               }
+       }
+        *str++ = '\0';
+       return(QSTR);
+       default:         return( c );
+       }
+}
+
+cpeek( c, yes, no ){
+       if( (peekc=getch()) != c ) return( no );
+       else {
+               peekc = -1;
+               return( yes );
+       }
+}
+
+getch(){
+       int ch;
+loop:
+       ch = (peekc < 0) ? getc(in) : peekc;
+       peekc = -1;
+       if(ch != EOF)return(ch);
+       if(++ifile > sargc){
+               if(ifile >= sargc+2)getout();
+               in = stdin;
+               ln = 0;
+               goto loop;
+       }
+       fclose(in);
+       if((in = fopen(sargv[ifile],"r")) != NULL){
+               ln = 0;
+               ss = sargv[ifile];
+               goto loop;
+       }
+       yyerror("cannot open input file");
+}
+# define b_sp_max 3000
+int b_space [ b_sp_max ];
+int * b_sp_nxt = { b_space };
+
+int bdebug = 0;
+bundle(a){
+       int i, *p, *q;
+
+       p = &a;
+       i = *p++;
+       q = b_sp_nxt;
+       if( bdebug ) printf("bundle %d elements at %o\n",i,  q );
+       while(i-- > 0){
+               if( b_sp_nxt >= & b_space[b_sp_max] ) yyerror( "bundling space exceeded" );
+               * b_sp_nxt++ = *p++;
+       }
+       * b_sp_nxt++ = 0;
+       yyval = q;
+       return( q );
+}
+
+routput(p) int *p; {
+       if( bdebug ) printf("routput(%o)\n", p );
+       if( p >= &b_space[0] && p < &b_space[b_sp_max]){
+               /* part of a bundle */
+               while( *p != 0 ) routput( *p++ );
+       }
+       else printf( p );        /* character string */
+}
+
+output( p ) int *p; {
+       routput( p );
+       b_sp_nxt = & b_space[0];
+       printf( "\n" );
+       fflush(stdout);
+       cp = cary;
+       crs = rcrs;
+}
+
+conout( p, s ) int *p; char *s; {
+       printf("[");
+       routput( p );
+       printf("]s%s\n", s );
+       fflush(stdout);
+       lev--;
+}
+
+yyerror( s ) char *s; {
+       if(ifile > sargc)ss="teletype";
+       printf("c[%s on line %d, %s]pc\n", s ,ln+1,ss);
+       fflush(stdout);
+       cp = cary;
+       crs = rcrs;
+       bindx = 0;
+       lev = 0;
+       b_sp_nxt = &b_space[0];
+}
+
+pp( s ) char *s; {
+       /* puts the relevant stuff on pre and post for the letter s */
+
+       bundle(3, "S", s, pre );
+       pre = yyval;
+       bundle(4, post, "L", s, "s." );
+       post = yyval;
+}
+
+tp( s ) char *s; { /* same as pp, but for temps */
+       bundle(3, "0S", s, pre );
+       pre = yyval;
+       bundle(4, post, "L", s, "s." );
+       post = yyval;
+}
+
+yyinit(argc,argv) int argc; char *argv[];{
+       signal( 2, (int(*)())1 );       /* ignore all interrupts */
+       sargv=argv;
+       sargc= -- argc;
+       if(sargc == 0)in=stdin;
+       else if((in = fopen(sargv[1],"r")) == NULL)
+               yyerror("cannot open input file");
+       ifile = 1;
+       ln = 0;
+       ss = sargv[1];
+}
+int *getout(){
+       printf("q");
+       fflush(stdout);
+       exit();
+}
+
+int *
+getf(p) char *p;{
+       return(&funtab[2*(*p -0141)]);
+}
+int *
+geta(p) char *p;{
+       return(&atab[2*(*p - 0141)]);
+}
+
+main(argc, argv)
+char **argv;
+{
+       int p[2];
+
+
+       if (argc > 1 && *argv[1] == '-') {
+               if((argv[1][1] == 'd')||(argv[1][1] == 'c')){
+                       yyinit(--argc, ++argv);
+                       yyparse();
+                       exit();
+               }
+               if(argv[1][1] != 'l'){
+                       printf("unrecognizable argument\n");
+                       fflush(stdout);
+                       exit();
+               }
+               argv[1] = "/usr/lib/lib.b";
+       }
+       pipe(p);
+       if (fork()==0) {
+               close(1);
+               dup(p[1]);
+               close(p[0]);
+               close(p[1]);
+               yyinit(argc, argv);
+               yyparse();
+               exit();
+       }
+       close(0);
+       dup(p[0]);
+       close(p[0]);
+       close(p[1]);
+       execl("/bin/dc", "dc", "-", 0);
+       execl("/usr/bin/dc", "dc", "-", 0);
+}
diff --git a/usr/src/cmd/cal.c b/usr/src/cmd/cal.c
new file mode 100644 (file)
index 0000000..432a37d
--- /dev/null
@@ -0,0 +1,204 @@
+char   dayw[] = {
+       " S  M Tu  W Th  F  S"
+};
+char   *smon[]= {
+       "January", "February", "March", "April",
+       "May", "June", "July", "August",
+       "September", "October", "November", "December",
+};
+char   string[432];
+main(argc, argv)
+char *argv[];
+{
+       register y, i, j;
+       int m;
+
+       if(argc < 2) {
+               printf("usage: cal [month] year\n");
+               exit(0);
+       }
+       if(argc == 2)
+               goto xlong;
+
+/*
+ *     print out just month
+ */
+
+       m = number(argv[1]);
+       if(m<1 || m>12)
+               goto badarg;
+       y = number(argv[2]);
+       if(y<1 || y>9999)
+               goto badarg;
+       printf("   %s %u\n", smon[m-1], y);
+       printf("%s\n", dayw);
+       cal(m, y, string, 24);
+       for(i=0; i<6*24; i+=24)
+               pstr(string+i, 24);
+       exit(0);
+
+/*
+ *     print out complete year
+ */
+
+xlong:
+       y = number(argv[1]);
+       if(y<1 || y>9999)
+               goto badarg;
+       printf("\n\n\n");
+       printf("                                %u\n", y);
+       printf("\n");
+       for(i=0; i<12; i+=3) {
+               for(j=0; j<6*72; j++)
+                       string[j] = '\0';
+               printf("         %.3s", smon[i]);
+               printf("                        %.3s", smon[i+1]);
+               printf("                       %.3s\n", smon[i+2]);
+               printf("%s   %s   %s\n", dayw, dayw, dayw);
+               cal(i+1, y, string, 72);
+               cal(i+2, y, string+23, 72);
+               cal(i+3, y, string+46, 72);
+               for(j=0; j<6*72; j+=72)
+                       pstr(string+j, 72);
+       }
+       printf("\n\n\n");
+       exit(0);
+
+badarg:
+       printf("Bad argument\n");
+}
+
+number(str)
+char *str;
+{
+       register n, c;
+       register char *s;
+
+       n = 0;
+       s = str;
+       while(c = *s++) {
+               if(c<'0' || c>'9')
+                       return(0);
+               n = n*10 + c-'0';
+       }
+       return(n);
+}
+
+pstr(str, n)
+char *str;
+{
+       register i;
+       register char *s;
+
+       s = str;
+       i = n;
+       while(i--)
+               if(*s++ == '\0')
+                       s[-1] = ' ';
+       i = n+1;
+       while(i--)
+               if(*--s != ' ')
+                       break;
+       s[1] = '\0';
+       printf("%s\n", str);
+}
+
+char   mon[] = {
+       0,
+       31, 29, 31, 30,
+       31, 30, 31, 31,
+       30, 31, 30, 31,
+};
+
+cal(m, y, p, w)
+char *p;
+{
+       register d, i;
+       register char *s;
+
+       s = p;
+       d = jan1(y);
+       mon[2] = 29;
+       mon[9] = 30;
+
+       switch((jan1(y+1)+7-d)%7) {
+
+       /*
+        *      non-leap year
+        */
+       case 1:
+               mon[2] = 28;
+               break;
+
+       /*
+        *      1752
+        */
+       default:
+               mon[9] = 19;
+               break;
+
+       /*
+        *      leap year
+        */
+       case 2:
+               ;
+       }
+       for(i=1; i<m; i++)
+               d += mon[i];
+       d %= 7;
+       s += 3*d;
+       for(i=1; i<=mon[m]; i++) {
+               if(i==3 && mon[m]==19) {
+                       i += 11;
+                       mon[m] += 11;
+               }
+               if(i > 9)
+                       *s = i/10+'0';
+               s++;
+               *s++ = i%10+'0';
+               s++;
+               if(++d == 7) {
+                       d = 0;
+                       s = p+w;
+                       p = s;
+               }
+       }
+}
+
+/*
+ *     return day of the week
+ *     of jan 1 of given year
+ */
+
+jan1(yr)
+{
+       register y, d;
+
+/*
+ *     normal gregorian calendar
+ *     one extra day per four years
+ */
+
+       y = yr;
+       d = 4+y+(y+3)/4;
+
+/*
+ *     julian calendar
+ *     regular gregorian
+ *     less three days per 400
+ */
+
+       if(y > 1800) {
+               d -= (y-1701)/100;
+               d += (y-1601)/400;
+       }
+
+/*
+ *     great calendar changeover instant
+ */
+
+       if(y > 1752)
+               d += 3;
+
+       return(d%7);
+}
diff --git a/usr/src/cmd/call.c b/usr/src/cmd/call.c
new file mode 100644 (file)
index 0000000..9723e88
--- /dev/null
@@ -0,0 +1,42 @@
+char *dn;
+
+main(argc, argv)
+char *argv[];
+{
+       register f, n, c;
+
+
+       if(argc < 2)
+               goto arg;
+       dn = "/dev/dn0";
+       if(*argv[1] == '-') {
+               dn = argv[1]+1;
+               argc--;
+               argv++;
+       }
+       if(argc < 2)
+               goto arg;
+       c = 0;
+loop:
+       f = open(dn, 1);
+       if(f < 0)
+               goto slp;
+       for(n=0; argv[1][n]; n++)
+               ;
+       alarm(120);
+       if(write(f, argv[1], n) == n)
+               exit(0);
+
+slp:
+       if(f >= 0)
+               close(f);
+       c++;
+       if(c > 100)
+               exit(1);
+       sleep(10);
+       goto loop;
+
+arg:
+       printf("arg c\n");
+       exit(1);
+}
diff --git a/usr/src/cmd/cat.c b/usr/src/cmd/cat.c
new file mode 100644 (file)
index 0000000..e0f4ef6
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Concatenate files.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+char   stdbuf[BUFSIZ];
+
+main(argc, argv)
+char **argv;
+{
+       int fflg = 0;
+       register FILE *fi;
+       register c;
+       int dev, ino = -1;
+       struct stat statb;
+
+       setbuf(stdout, stdbuf);
+       for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
+               switch(argv[1][1]) {
+               case 0:
+                       break;
+               case 'u':
+                       setbuf(stdout, (char *)NULL);
+                       continue;
+               }
+               break;
+       }
+       fstat(fileno(stdout), &statb);
+       statb.st_mode &= S_IFMT;
+       if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
+               dev = statb.st_dev;
+               ino = statb.st_ino;
+       }
+       if (argc < 2) {
+               argc = 2;
+               fflg++;
+       }
+       while (--argc > 0) {
+               if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
+                       fi = stdin;
+               else {
+                       if ((fi = fopen(*argv, "r")) == NULL) {
+                               fprintf(stderr, "cat: can't open %s\n", *argv);
+                               continue;
+                       }
+               }
+               fstat(fileno(fi), &statb);
+               if (statb.st_dev==dev && statb.st_ino==ino) {
+                       fprintf(stderr, "cat: input %s is output\n",
+                          fflg?"-": *argv);
+                       fclose(fi);
+                       continue;
+               }
+               while ((c = getc(fi)) != EOF)
+                       putchar(c);
+               if (fi!=stdin)
+                       fclose(fi);
+       }
+       return(0);
+}
diff --git a/usr/src/cmd/cb.c b/usr/src/cmd/cb.c
new file mode 100644 (file)
index 0000000..6452ae2
--- /dev/null
@@ -0,0 +1,357 @@
+#include <stdio.h>
+int    slevel[10];
+int    clevel  = 0;
+int    spflg[20][10];
+int    sind[20][10];
+int    siflev[10];
+int    sifflg[10];
+int    iflev   = 0;
+int    ifflg   = -1;
+int    level   = 0;
+int    ind[10] = {
+       0,0,0,0,0,0,0,0,0,0 };
+int    eflg    = 0;
+int    paren   = 0;
+int    pflg[10] = {
+       0,0,0,0,0,0,0,0,0,0 };
+char   lchar;
+char   pchar;
+int    aflg    = 0;
+int    ct;
+int    stabs[20][10];
+int    qflg    = 0;
+char   *wif[] = {
+       "if",0};
+char   *welse[] = {
+       "else",0};
+char   *wfor[] = {
+       "for",0};
+char   *wds[] = {
+       "case","default",0};
+int    j       = 0;
+char   string[200];
+char   cc;
+int    sflg    = 1;
+int    peek    = -1;
+int    tabs    = 0;
+int    lastchar;
+int    c;
+main(argc,argv) int argc;
+char argv[];
+{
+       while((c = getch()) != EOF){
+               switch(c){
+               case ' ':
+               case '\t':
+                       if(lookup(welse) == 1){
+                               gotelse();
+                               if(sflg == 0 || j > 0)string[j++] = c;
+                               puts();
+                               sflg = 0;
+                               continue;
+                       }
+                       if(sflg == 0 || j > 0)string[j++] = c;
+                       continue;
+               case '\n':
+                       if((eflg = lookup(welse)) == 1)gotelse();
+                       puts();
+                       printf("\n");
+                       sflg = 1;
+                       if(eflg == 1){
+                               pflg[level]++;
+                               tabs++;
+                       }
+                       else
+                               if(pchar == lchar)
+                                       aflg = 1;
+                       continue;
+               case '{':
+                       if(lookup(welse) == 1)gotelse();
+                       siflev[clevel] = iflev;
+                       sifflg[clevel] = ifflg;
+                       iflev = ifflg = 0;
+                       clevel++;
+                       if(sflg == 1 && pflg[level] != 0){
+                               pflg[level]--;
+                               tabs--;
+                       }
+                       string[j++] = c;
+                       puts();
+                       getnl();
+                       puts();
+                       printf("\n");
+                       tabs++;
+                       sflg = 1;
+                       if(pflg[level] > 0){
+                               ind[level] = 1;
+                               level++;
+                               slevel[level] = clevel;
+                       }
+                       continue;
+               case '}':
+                       clevel--;
+                       if((iflev = siflev[clevel]-1) < 0)iflev = 0;
+                       ifflg = sifflg[clevel];
+                       if(pflg[level] >0 && ind[level] == 0){
+                               tabs -= pflg[level];
+                               pflg[level] = 0;
+                       }
+                       puts();
+                       tabs--;
+                       ptabs();
+                       if((peek = getch()) == ';'){
+                               printf("%c;",c);
+                               peek = -1;
+                       }
+                       else printf("%c",c);
+                       getnl();
+                       puts();
+                       printf("\n");
+                       sflg = 1;
+                       if(clevel < slevel[level])if(level > 0)level--;
+                       if(ind[level] != 0){
+                               tabs -= pflg[level];
+                               pflg[level] = 0;
+                               ind[level] = 0;
+                       }
+                       continue;
+               case '"':
+               case '\'':
+                       string[j++] = c;
+                       while((cc = getch()) != c){
+                               string[j++] = cc;
+                               if(cc == '\\'){
+                                       string[j++] = getch();
+                               }
+                               if(cc == '\n'){
+                                       puts();
+                                       sflg = 1;
+                               }
+                       }
+                       string[j++] = cc;
+                       if(getnl() == 1){
+                               lchar = cc;
+                               peek = '\n';
+                       }
+                       continue;
+               case ';':
+                       string[j++] = c;
+                       puts();
+                       if(pflg[level] > 0 && ind[level] == 0){
+                               tabs -= pflg[level];
+                               pflg[level] = 0;
+                       }
+                       getnl();
+                       puts();
+                       printf("\n");
+                       sflg = 1;
+                       if(iflev > 0)
+                               if(ifflg == 1){iflev--;
+                                       ifflg = 0;
+                               }
+                               else iflev = 0;
+                       continue;
+               case '\\':
+                       string[j++] = c;
+                       string[j++] = getch();
+                       continue;
+               case '?':
+                       qflg = 1;
+                       string[j++] = c;
+                       continue;
+               case ':':
+                       string[j++] = c;
+                       if(qflg == 1){
+                               qflg = 0;
+                               continue;
+                       }
+                       if(lookup(wds) == 0){
+                               sflg = 0;
+                               puts();
+                       }
+                       else{
+                               tabs--;
+                               puts();
+                               tabs++;
+                       }
+                       if((peek = getch()) == ';'){
+                               printf(";");
+                               peek = -1;
+                       }
+                       getnl();
+                       puts();
+                       printf("\n");
+                       sflg = 1;
+                       continue;
+               case '/':
+                       string[j++] = c;
+                       if((peek = getch()) != '*')continue;
+                       string[j++] = peek;
+                       peek = -1;
+                       comment();
+                       continue;
+               case ')':
+                       paren--;
+                       string[j++] = c;
+                       puts();
+                       if(getnl() == 1){
+                               peek = '\n';
+                               if(paren != 0)aflg = 1;
+                               else if(tabs > 0){
+                                       pflg[level]++;
+                                       tabs++;
+                                       ind[level] = 0;
+                               }
+                       }
+                       continue;
+               case '#':
+                       string[j++] = c;
+                       while((cc = getch()) != '\n')string[j++] = cc;
+                       string[j++] = cc;
+                       sflg = 0;
+                       puts();
+                       sflg = 1;
+                       continue;
+               case '(':
+                       string[j++] = c;
+                       paren++;
+                       if(lookup(wfor) == 1){
+                               while((c = gets()) != ';');
+                               ct=0;
+cont:
+                               while((c = gets()) != ')'){
+                                       if(c == '(') ct++;
+                               }
+                               if(ct != 0){
+                                       ct--;
+                                       goto cont;
+                               }
+                               paren--;
+                               puts();
+                               if(getnl() == 1){
+                                       peek = '\n';
+                                       pflg[level]++;
+                                       tabs++;
+                                       ind[level] = 0;
+                               }
+                               continue;
+                       }
+                       if(lookup(wif) == 1){
+                               puts();
+                               stabs[clevel][iflev] = tabs;
+                               spflg[clevel][iflev] = pflg[level];
+                               sind[clevel][iflev] = ind[level];
+                               iflev++;
+                               ifflg = 1;
+                       }
+                       continue;
+               default:
+                       string[j++] = c;
+                       if(c != ',')lchar = c;
+               }
+       }
+}
+ptabs(){
+       int i;
+       for(i=0; i < tabs; i++)printf("\t");
+}
+getch(){
+       if(peek < 0 && lastchar != ' ' && lastchar != '\t')pchar = lastchar;
+       lastchar = (peek<0) ? getc(stdin):peek;
+       peek = -1;
+       return(lastchar);
+}
+puts(){
+       if(j > 0){
+               if(sflg != 0){
+                       ptabs();
+                       sflg = 0;
+                       if(aflg == 1){
+                               aflg = 0;
+                               if(tabs > 0)printf("    ");
+                       }
+               }
+               string[j] = '\0';
+               printf("%s",string);
+               j = 0;
+       }
+       else{
+               if(sflg != 0){
+                       sflg = 0;
+                       aflg = 0;
+               }
+       }
+}
+lookup(tab)
+char *tab[];
+{
+       char r;
+       int l,kk,k,i;
+       if(j < 1)return(0);
+       kk=0;
+       while(string[kk] == ' ')kk++;
+       for(i=0; tab[i] != 0; i++){
+               l=0;
+               for(k=kk;(r = tab[i][l++]) == string[k] && r != '\0';k++);
+               if(r == '\0' && (string[k] < 'a' || string[k] > 'z' || k >= j))return(1);
+       }
+       return(0);
+}
+gets(){
+       char ch;
+beg:
+       if((ch = string[j++] = getch()) == '\\'){
+               string[j++] = getch();
+               goto beg;
+       }
+       if(ch == '\'' || ch == '"'){
+               while((cc = string[j++] = getch()) != ch)if(cc == '\\')string[j++] = getch();
+               goto beg;
+       }
+       if(ch == '\n'){
+               puts();
+               aflg = 1;
+               goto beg;
+       }
+       else return(ch);
+}
+gotelse(){
+       tabs = stabs[clevel][iflev];
+       pflg[level] = spflg[clevel][iflev];
+       ind[level] = sind[clevel][iflev];
+       ifflg = 1;
+}
+getnl(){
+       while((peek = getch()) == '\t' || peek == ' '){
+               string[j++] = peek;
+               peek = -1;
+       }
+       if((peek = getch()) == '/'){
+               peek = -1;
+               if((peek = getch()) == '*'){
+                       string[j++] = '/';
+                       string[j++] = '*';
+                       peek = -1;
+                       comment();
+               }
+               else string[j++] = '/';
+       }
+       if((peek = getch()) == '\n'){
+               peek = -1;
+               return(1);
+       }
+       return(0);
+}
+comment(){
+rep:
+       while((c = string[j++] = getch()) != '*')
+               if(c == '\n'){
+                       puts();
+                       sflg = 1;
+               }
+gotstar:
+       if((c = string[j++] = getch()) != '/'){
+               if(c == '*')goto gotstar;
+               goto rep;
+       }
+}
diff --git a/usr/src/cmd/checkeq.c b/usr/src/cmd/checkeq.c
new file mode 100644 (file)
index 0000000..f60a127
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+FILE   *fin;
+int    delim   = '$';
+
+main(argc, argv) char **argv; {
+
+       if (argc <= 1)
+               check(stdin);
+       else
+               while (--argc > 0) {
+                       if ((fin = fopen(*++argv, "r")) == NULL) {
+                               printf("Can't open %s\n", *argv);
+                               exit(1);
+                       }
+                       printf("%s:\n", *argv);
+                       check(fin);
+                       fclose(fin);
+               }
+}
+
+check(f)
+FILE   *f;
+{
+       int start, line, eq, ndel, totdel;
+       char in[600], *p;
+
+       start = eq = line = ndel = totdel = 0;
+       while (fgets(in, 600, f) != NULL) {
+               line++;
+               ndel = 0;
+               for (p = in; *p; p++)
+                       if (*p == delim)
+                               ndel++;
+               if (*in=='.' && *(in+1)=='E' && *(in+2)=='Q') {
+                       if (eq++)
+                               printf("   Spurious EQ, line %d\n", line);
+                       if (totdel)
+                               printf("   EQ in %c%c, line %d\n", delim, delim, line);
+               } else if (*in=='.' && *(in+1)=='E' && *(in+2)=='N') {
+                       if (eq==0)
+                               printf("   Spurious EN, line %d\n", line);
+                       else
+                               eq = 0;
+                       if (totdel > 0)
+                               printf("   EN in %c%c, line %d\n", delim, delim, line);
+                       start = 0;
+               } else if (eq && *in=='d' && *(in+1)=='e' && *(in+2)=='l' && *(in+3)=='i' && *(in+4)=='m') {
+                       for (p=in+5; *p; p++)
+                               if (*p != ' ') {
+                                       if (*p == 'o' && *(p+1) == 'f')
+                                               delim = 0;
+                                       else
+                                               delim = *p;
+                                       break;
+                               }
+                       if (delim == 0)
+                               printf("   Delim off, line %d\n", line);
+                       else
+                               printf("   New delims %c%c, line %d\n", delim, delim, line);
+               }
+               if (ndel > 0 && eq > 0)
+                       printf("   %c%c in EQ, line %d\n", delim, delim, line);
+               if (ndel == 0)
+                       continue;
+               totdel += ndel;
+               if (totdel%2) {
+                       if (start == 0)
+                               start = line;
+                       else {
+                               printf("   %d line %c%c, lines %d-%d\n", line-start+1, delim, delim, start, line);
+                               start = line;
+                       }
+               } else {
+                       if (start > 0) {
+                               printf("   %d line %c%c, lines %d-%d\n", line-start+1, delim, delim, start, line);
+                               start = 0;
+                       }
+                       totdel = 0;
+               }
+       }
+       if (totdel)
+               printf("   Unfinished %c%c\n", delim, delim);
+       if (eq)
+               printf("   Unfinished EQ\n");
+}
diff --git a/usr/src/cmd/chgrp.c b/usr/src/cmd/chgrp.c
new file mode 100644 (file)
index 0000000..13b23ff
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * chgrp gid file ...
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <grp.h>
+
+struct group   *gr,*getgrnam();
+struct stat    stbuf;
+int    gid;
+int    status;
+
+main(argc, argv)
+char *argv[];
+{
+       register c;
+
+       if(argc < 3) {
+               printf("usage: chgrp gid file ...\n");
+               exit(4);
+       }
+       if(isnumber(argv[1])) {
+               gid = atoi(argv[1]);
+       } else {
+               if((gr=getgrnam(argv[1])) == NULL) {
+                       printf("unknown group: %s\n",argv[1]);
+                       exit(4);
+               }
+               gid = gr->gr_gid;
+       }
+       for(c=2; c<argc; c++) {
+               stat(argv[c], &stbuf);
+               if(chown(argv[c], stbuf.st_uid, gid) < 0) {
+                       perror(argv[c]);
+                       status = 1;
+               }
+       }
+       exit(status);
+}
+
+isnumber(s)
+char *s;
+{
+       register c;
+
+       while(c = *s++)
+               if(!isdigit(c))
+                       return(0);
+       return(1);
+}
diff --git a/usr/src/cmd/chmod.c b/usr/src/cmd/chmod.c
new file mode 100644 (file)
index 0000000..4d09ad0
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * chmod [ugoa][+-=][rwxstugo] files
+ *  change mode of files
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define        USER    05700   /* user's bits */
+#define        GROUP   02070   /* group's bits */
+#define        OTHER   00007   /* other's bits */
+#define        ALL     01777   /* all (note absence of setuid, etc) */
+
+#define        READ    00444   /* read permit */
+#define        WRITE   00222   /* write permit */
+#define        EXEC    00111   /* exec permit */
+#define        SETID   06000   /* set[ug]id */
+#define        STICKY  01000   /* sticky bit */
+
+char   *ms;
+int    um;
+struct stat st;
+
+main(argc,argv)
+char **argv;
+{
+       register i;
+       register char *p;
+       int status = 0;
+
+       if (argc < 3) {
+               fprintf(stderr, "Usage: chmod [ugoa][+-=][rwxstugo] file ...\n");
+               exit(255);
+       }
+       ms = argv[1];
+       um = umask(0);
+       newmode(0);
+       for (i = 2; i < argc; i++) {
+               p = argv[i];
+               if (stat(p, &st) < 0) {
+                       fprintf(stderr, "chmod: can't access %s\n", p);
+                       ++status;
+                       continue;
+               }
+               ms = argv[1];
+               if (chmod(p, newmode(st.st_mode)) < 0) {
+                       fprintf(stderr, "chmod: can't change %s\n", p);
+                       ++status;
+                       continue;
+               }
+       }
+       exit(status);
+}
+
+newmode(nm)
+unsigned nm;
+{
+       register o, m, b;
+
+       m = abs();
+       if (!*ms)
+               return(m);
+       do {
+               m = who();
+               while (o = what()) {
+                       b = where(nm);
+                       switch (o) {
+                       case '+':
+                               nm |= b & m;
+                               break;
+                       case '-':
+                               nm &= ~(b & m);
+                               break;
+                       case '=':
+                               nm &= ~m;
+                               nm |= b & m;
+                               break;
+                       }
+               }
+       } while (*ms++ == ',');
+       if (*--ms) {
+               fprintf(stderr, "chmod: invalid mode\n");
+               exit(255);
+       }
+       return(nm);
+}
+
+abs()
+{
+       register c, i;
+
+       i = 0;
+       while ((c = *ms++) >= '0' && c <= '7')
+               i = (i << 3) + (c - '0');
+       ms--;
+       return(i);
+}
+
+who()
+{
+       register m;
+
+       m = 0;
+       for (;;) switch (*ms++) {
+       case 'u':
+               m |= USER;
+               continue;
+       case 'g':
+               m |= GROUP;
+               continue;
+       case 'o':
+               m |= OTHER;
+               continue;
+       case 'a':
+               m |= ALL;
+               continue;
+       default:
+               ms--;
+               if (m == 0)
+                       m = ALL & ~um;
+               return m;
+       }
+}
+
+what()
+{
+       switch (*ms) {
+       case '+':
+       case '-':
+       case '=':
+               return *ms++;
+       }
+       return(0);
+}
+
+where(om)
+register om;
+{
+       register m;
+
+       m = 0;
+       switch (*ms) {
+       case 'u':
+               m = (om & USER) >> 6;
+               goto dup;
+       case 'g':
+               m = (om & GROUP) >> 3;
+               goto dup;
+       case 'o':
+               m = (om & OTHER);
+       dup:
+               m &= (READ|WRITE|EXEC);
+               m |= (m << 3) | (m << 6);
+               ++ms;
+               return m;
+       }
+       for (;;) switch (*ms++) {
+       case 'r':
+               m |= READ;
+               continue;
+       case 'w':
+               m |= WRITE;
+               continue;
+       case 'x':
+               m |= EXEC;
+               continue;
+       case 's':
+               m |= SETID;
+               continue;
+       case 't':
+               m |= STICKY;
+               continue;
+       default:
+               ms--;
+               return m;
+       }
+}
diff --git a/usr/src/cmd/chown.c b/usr/src/cmd/chown.c
new file mode 100644 (file)
index 0000000..edfa00e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * chown uid file ...
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+struct passwd  *pwd,*getpwnam();
+struct stat    stbuf;
+int    uid;
+int    status;
+
+main(argc, argv)
+char *argv[];
+{
+       register c;
+
+       if(argc < 3) {
+               printf("usage: chown uid file ...\n");
+               exit(4);
+       }
+       if(isnumber(argv[1])) {
+               uid = atoi(argv[1]);
+               goto cho;
+       }
+       if((pwd=getpwnam(argv[1])) == NULL) {
+               printf("unknown user id: %s\n",argv[1]);
+               exit(4);
+       }
+       uid = pwd->pw_uid;
+
+cho:
+       for(c=2; c<argc; c++) {
+               stat(argv[c], &stbuf);
+               if(chown(argv[c], uid, stbuf.st_gid) < 0) {
+                       perror(argv[c]);
+                       status = 1;
+               }
+       }
+       exit(status);
+}
+
+isnumber(s)
+char *s;
+{
+       register c;
+
+       while(c = *s++)
+               if(!isdigit(c))
+                       return(0);
+       return(1);
+}
diff --git a/usr/src/cmd/cmp.c b/usr/src/cmd/cmp.c
new file mode 100644 (file)
index 0000000..4400b85
--- /dev/null
@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <ctype.h>
+
+FILE   *file1,*file2;
+int    eflg;
+int    lflg    = 1;
+long   line    = 1;
+long   chr     = 0;
+long   skip1;
+long   skip2;
+
+long   otoi();
+
+main(argc, argv)
+char **argv;
+{
+       register c1, c2;
+       char *arg;
+
+       if(argc < 3)
+               goto narg;
+       arg = argv[1];
+       if(arg[0] == '-' && arg[1] == 's') {
+               lflg--;
+               argv++;
+               argc--;
+       }
+       arg = argv[1];
+       if(arg[0] == '-' && arg[1] == 'l') {
+               lflg++;
+               argv++;
+               argc--;
+       }
+       if(argc < 3)
+               goto narg;
+       arg = argv[1];
+       if( arg[0]=='-' && arg[1]==0 )
+               file1 = stdin;
+       else if((file1 = fopen(arg, "r")) == NULL)
+               goto barg;
+       arg = argv[2];
+       if((file2 = fopen(arg, "r")) == NULL)
+               goto barg;
+       if (argc>3)
+               skip1 = otoi(argv[3]);
+       if (argc>4)
+               skip2 = otoi(argv[4]);
+       while (skip1) {
+               if ((c1 = getc(file1)) == EOF) {
+                       arg = argv[1];
+                       goto earg;
+               }
+               skip1--;
+       }
+       while (skip2) {
+               if ((c2 = getc(file2)) == EOF) {
+                       arg = argv[2];
+                       goto earg;
+               }
+               skip2--;
+       }
+
+loop:
+       chr++;
+       c1 = getc(file1);
+       c2 = getc(file2);
+       if(c1 == c2) {
+               if (c1 == '\n')
+                       line++;
+               if(c1 == EOF) {
+                       if(eflg)
+                               exit(1);
+                       exit(0);
+               }
+               goto loop;
+       }
+       if(lflg == 0)
+               exit(1);
+       if(c1 == EOF) {
+               arg = argv[1];
+               goto earg;
+       }
+       if(c2 == EOF)
+               goto earg;
+       if(lflg == 1) {
+               printf("%s %s differ: char %ld, line %ld\n", argv[1], arg,
+                       chr, line);
+               exit(1);
+       }
+       eflg = 1;
+       printf("%6ld %3o %3o\n", chr, c1, c2);
+       goto loop;
+
+narg:
+       printf("cmp: arg count\n");
+       exit(2);
+
+barg:
+       if (lflg)
+       printf("cmp: cannot open %s\n", arg);
+       exit(2);
+
+earg:
+       printf("cmp: EOF on %s\n", arg);
+       exit(1);
+}
+
+long otoi(s)
+char *s;
+{
+       long v;
+       int base;
+
+       v = 0;
+       base = 10;
+       if (*s == '0')
+               base = 8;
+       while(isdigit(*s))
+               v = v*base + *s++ - '0';
+       return(v);
+}
diff --git a/usr/src/cmd/col.c b/usr/src/cmd/col.c
new file mode 100644 (file)
index 0000000..c222405
--- /dev/null
@@ -0,0 +1,309 @@
+# include <stdio.h>
+# define PL 256
+# define ESC '\033'
+# define RLF '\013'
+# define SI '\017'
+# define SO '\016'
+# define GREEK 0200
+# define LINELN 800
+
+char *page[PL];
+char lbuff [LINELN], *line;
+int bflag, hflag, fflag;
+int half;
+int cp, lp;
+int ll, llh, mustwr;
+int pcp = 0;
+char *pgmname;
+char   *strcpy();
+
+main (argc, argv)
+       int argc; char **argv;
+{
+       int i;
+       int greek;
+       register int c;
+       char fbuff[BUFSIZ];
+
+       setbuf (stdout, fbuff);
+       pgmname = argv[0];
+
+       for (i = 1; i < argc; i++) {
+               register char *p;
+               if (*argv[i] != '-') {
+                       fprintf (stderr, "%s: bad option %s\n",
+                               pgmname, argv[i]);
+                       exit (2);
+               }
+               for (p = argv[i]+1; *p; p++) {
+                       switch (*p) {
+                       case 'b':
+                               bflag++;
+                               break;
+
+                       case 'h':
+                               hflag++;
+                               break;
+
+                       case 'f':
+                               fflag++;
+                               break;
+
+                       default:
+                               fprintf (stderr, "%s: bad option letter %c\n",
+                                       pgmname, *p);
+                               exit (2);
+                       }
+               }
+       }
+
+       for (ll=0; ll<PL; ll++)
+               page[ll] = 0;
+
+       cp = 0;
+       ll = 0;
+       greek = 0;
+       mustwr = PL;
+       line = lbuff;
+
+       while ((c = getchar()) != EOF) {
+               switch (c) {
+               case '\n':
+                       incr();
+                       incr();
+                       cp = 0;
+                       continue;
+
+               case '\0':
+                       continue;
+
+               case ESC:
+                       c = getchar();
+                       switch (c) {
+                       case '7':       /* reverse full line feed */
+                               decr();
+                               decr();
+                               break;
+
+                       case '8':       /* reverse half line feed */
+                               if (fflag)
+                                       decr();
+                               else {
+                                       if (--half < -1) {
+                                               decr();
+                                               decr();
+                                               half += 2;
+                                       }
+                               }
+                               break;
+
+                       case '9':       /* forward half line feed */
+                               if (fflag)
+                                       incr();
+                               else {
+                                       if (++half > 0) {
+                                               incr();
+                                               incr();
+                                               half -= 2;
+                                       }
+                               }
+                               break;
+                       }
+                       continue;
+
+               case SO:
+                       greek = GREEK;
+                       continue;
+
+               case SI:
+                       greek = 0;
+                       continue;
+
+               case RLF:
+                       decr();
+                       decr();
+                       continue;
+
+               case '\r':
+                       cp = 0;
+                       continue;
+
+               case '\t':
+                       cp = (cp + 8) & -8;
+                       continue;
+
+               case '\b':
+                       if (cp > 0)
+                               cp--;
+                       continue;
+
+               case ' ':
+                       cp++;
+                       continue;
+
+               default:
+                       c &= 0177;
+                       if (c > 040 && c < 0177) {      /* if printable */
+                               outc(c | greek);
+                               cp++;
+                       }
+                       continue;
+               }
+       }
+
+       for (i=0; i<PL; i++)
+               if (page[(mustwr+i)%PL] != 0)
+                       emit (page[(mustwr+i) % PL], mustwr+i-PL);
+       emit (" ", (llh + 1) & -2);
+       return 0;
+}
+
+outc (c)
+       register char c;
+{
+       if (lp > cp) {
+               line = lbuff;
+               lp = 0;
+       }
+
+       while (lp < cp) {
+               switch (*line) {
+               case '\0':
+                       *line = ' ';
+                       lp++;
+                       break;
+
+               case '\b':
+                       lp--;
+                       break;
+
+               default:
+                       lp++;
+               }
+               line++;
+       }
+       while (*line == '\b') {
+               line += 2;
+       }
+       if (bflag || *line == '\0' || *line == ' ')
+               *line = c;
+       else {
+               register char c1, c2, c3;
+               c1 = *++line;
+               *line++ = '\b';
+               c2 = *line;
+               *line++ = c;
+               while (c1) {
+                       c3 = *line;
+                       *line++ = c1;
+                       c1 = c2;
+                       c2 = c3;
+               }
+               lp = 0;
+               line = lbuff;
+       }
+}
+
+store (lno)
+{
+       char *malloc();
+
+       lno %= PL;
+       if (page[lno] != 0)
+               free (page[lno]);
+       page[lno] = malloc((unsigned)strlen(lbuff) + 2);
+       if (page[lno] == 0) {
+               fprintf (stderr, "%s: no storage\n", pgmname);
+               exit (2);
+       }
+       strcpy (page[lno],lbuff);
+}
+
+fetch(lno)
+{
+       register char *p;
+
+       lno %= PL;
+       p = lbuff;
+       while (*p)
+               *p++ = '\0';
+       line = lbuff;
+       lp = 0;
+       if (page[lno])
+               strcpy (line, page[lno]);
+}
+emit (s, lineno)
+       char *s;
+       int lineno;
+{
+       static int cline = 0;
+       register int ncp;
+       register char *p;
+       static int gflag = 0;
+
+       if (*s) {
+               while (cline < lineno - 1) {
+                       putchar ('\n');
+                       pcp = 0;
+                       cline += 2;
+               }
+               if (cline != lineno) {
+                       putchar (ESC);
+                       putchar ('9');
+                       cline++;
+               }
+               if (pcp)
+                       putchar ('\r');
+               pcp = 0;
+               p = s;
+               while (*p) {
+                       ncp = pcp;
+                       while (*p++ == ' ') {
+                               if ((++ncp & 7) == 0 && hflag) {
+                                       pcp = ncp;
+                                       putchar ('\t');
+                               }
+                       }
+                       if (!*--p)
+                               break;
+                       while (pcp < ncp) {
+                               putchar (' ');
+                               pcp++;
+                       }
+                       if (gflag != (*p & GREEK) && *p != '\b') {
+                               if (gflag)
+                                       putchar (SI);
+                               else
+                                       putchar (SO);
+                               gflag ^= GREEK;
+                       }
+                       putchar (*p & ~GREEK);
+                       if (*p++ == '\b')
+                               pcp--;
+                       else
+                               pcp++;
+               }
+       }
+}
+
+incr()
+{
+       store (ll++);
+       if (ll > llh)
+               llh = ll;
+       if (ll >= mustwr && page[ll%PL]) {
+               emit (page[ll%PL], ll - PL);
+               mustwr++;
+               free (page[ll%PL]);
+               page[ll%PL] = 0;
+       }
+       fetch (ll);
+}
+
+decr()
+{
+       if (ll > mustwr - PL) {
+               store (ll--);
+               fetch (ll);
+       }
+}
diff --git a/usr/src/cmd/comm.c b/usr/src/cmd/comm.c
new file mode 100644 (file)
index 0000000..a137ca3
--- /dev/null
@@ -0,0 +1,166 @@
+#include <stdio.h>
+#define LB 256
+int    one;
+int    two;
+int    three;
+
+char   *ldr[3];
+
+FILE *ib1;
+FILE *ib2;
+FILE *openfil();
+main(argc,argv)
+char   *argv[];
+{
+       int     l;
+       char    lb1[LB],lb2[LB];
+
+       ldr[0] = "";
+       ldr[1] = "\t";
+       ldr[2] = "\t\t";
+       if(argc > 1)  {
+               if(*argv[1] == '-' && argv[1][1] != 0) {
+                       l = 1;
+                       while(*++argv[1]) {
+                               switch(*argv[1]) {
+                               case'1':
+                                       if(!one) {
+                                               one = 1;
+                                               ldr[1][0] =
+                                               ldr[2][l--] = '\0';
+                                       }
+                                       break;
+                               case '2':
+                                       if(!two) {
+                                               two = 1;
+                                               ldr[2][l--] = '\0';
+                                       }
+                                       break;
+                               case '3':
+                                       three = 1;
+                                       break;
+                               default:
+                               fprintf(stderr,"comm: illegal flag\n");
+                               exit(1);
+                               }
+                       }
+                       argv++;
+                       argc--;
+               }
+       }
+
+       if(argc < 3) {
+               fprintf(stderr,"comm: arg count\n");
+               exit(1);
+       }
+
+       ib1 = openfil(argv[1]);
+       ib2 = openfil(argv[2]);
+
+
+       if(rd(ib1,lb1) < 0) {
+               if(rd(ib2,lb2) < 0)     exit(0);
+               copy(ib2,lb2,2);
+       }
+       if(rd(ib2,lb2) < 0)     copy(ib1,lb1,1);
+
+       while(1) {
+
+               switch(compare(lb1,lb2)) {
+
+                       case 0:
+                               wr(lb1,3);
+                               if(rd(ib1,lb1) < 0) {
+                                       if(rd(ib2,lb2) < 0)     exit(0);
+                                       copy(ib2,lb2,2);
+                               }
+                               if(rd(ib2,lb2) < 0)     copy(ib1,lb1,1);
+                               continue;
+
+                       case 1:
+                               wr(lb1,1);
+                               if(rd(ib1,lb1) < 0)     copy(ib2,lb2,2);
+                               continue;
+
+                       case 2:
+                               wr(lb2,2);
+                               if(rd(ib2,lb2) < 0)     copy(ib1,lb1,1);
+                               continue;
+               }
+       }
+}
+
+rd(file,buf)
+FILE *file;
+char *buf;
+{
+
+       register int i, c;
+       i = 0;
+       while((c = getc(file)) != EOF) {
+               *buf = c;
+               if(c == '\n' || i > LB-2) {
+                       *buf = '\0';
+                       return(0);
+               }
+               i++;
+               buf++;
+       }
+       return(-1);
+}
+
+wr(str,n)
+       char    *str;
+{
+
+       switch(n) {
+
+               case 1:
+                       if(one) return;
+                       break;
+
+               case 2:
+                       if(two) return;
+                       break;
+
+               case 3:
+                       if(three)       return;
+       }
+       printf("%s%s\n",ldr[n-1],str);
+}
+
+copy(ibuf,lbuf,n)
+FILE *ibuf;
+char *lbuf;
+{
+       do {
+               wr(lbuf,n);
+       } while(rd(ibuf,lbuf) >= 0);
+
+       exit(0);
+}
+
+compare(a,b)
+       char    *a,*b;
+{
+       register char *ra,*rb;
+
+       ra = --a;
+       rb = --b;
+       while(*++ra == *++rb)
+               if(*ra == '\0') return(0);
+       if(*ra < *rb)   return(1);
+       return(2);
+}
+FILE *openfil(s)
+char *s;
+{
+       FILE *b;
+       if(s[0]=='-' && s[1]==0)
+               b = stdin;
+       else if((b=fopen(s,"r")) == NULL) {
+               fprintf(stderr,"comm: cannot open %s\n",s);
+               exit(1);
+       }
+       return(b);
+}
diff --git a/usr/src/cmd/cron.c b/usr/src/cmd/cron.c
new file mode 100644 (file)
index 0000000..b10c8b3
--- /dev/null
@@ -0,0 +1,252 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#define        LISTS   512
+
+#define        EXACT   0
+#define        ANY     1
+#define        LIST    2
+#define        RANGE   3
+#define        EOS     4
+char   crontab[]       = "/usr/lib/crontab";
+time_t itime;
+struct tm *loct;
+struct tm *localtime();
+char   *malloc();
+char   *realloc();
+int    flag;
+char   *list;
+unsigned listsize;
+
+main()
+{
+       register char *cp;
+       char *cmp();
+       time_t filetime = 0;
+
+       setuid(1);
+       if (fork())
+               exit(0);
+       chdir("/");
+       freopen(crontab, "r", stdin);
+       freopen("/", "r", stdout);
+       freopen("/", "r", stderr);
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       time(&itime);
+       itime -= localtime(&itime)->tm_sec;
+       fclose(stdin);
+
+       for (;; itime+=60, slp()) {
+               struct stat cstat;
+
+               if (stat(crontab, &cstat) == -1)
+                       continue;
+               if (cstat.st_mtime > filetime) {
+                       filetime = cstat.st_mtime;
+                       init();
+               }
+               loct = localtime(&itime);
+               loct->tm_mon++;          /* 1-12 for month */
+               for(cp = list; *cp != EOS;) {
+                       flag = 0;
+                       cp = cmp(cp, loct->tm_min);
+                       cp = cmp(cp, loct->tm_hour);
+                       cp = cmp(cp, loct->tm_mday);
+                       cp = cmp(cp, loct->tm_mon);
+                       cp = cmp(cp, loct->tm_wday);
+                       if(flag == 0) {
+                               slp();
+                               ex(cp);
+                       }
+                       while(*cp++ != 0)
+                               ;
+               }
+       }
+}
+
+char *
+cmp(p, v)
+char *p;
+{
+       register char *cp;
+
+       cp = p;
+       switch(*cp++) {
+
+       case EXACT:
+               if (*cp++ != v)
+                       flag++;
+               return(cp);
+
+       case ANY:
+               return(cp);
+
+       case LIST:
+               while(*cp != LIST)
+                       if(*cp++ == v) {
+                               while(*cp++ != LIST)
+                                       ;
+                               return(cp);
+                       }
+               flag++;
+               return(cp+1);
+
+       case RANGE:
+               if(*cp > v || cp[1] < v)
+                       flag++;
+               return(cp+2);
+       }
+       if(cp[-1] != v)
+               flag++;
+       return(cp);
+}
+
+slp()
+{
+       register i;
+       time_t t;
+
+       time(&t);
+       i = itime - t;
+       if(i > 0)
+               sleep(i);
+}
+
+ex(s)
+char *s;
+{
+       int st;
+
+       if(fork()) {
+               wait(&st);
+               return;
+       }
+       if(fork())
+               exit(0);
+       freopen("/", "r", stdin);
+       execl("/bin/sh", "sh", "-c", s, 0);
+       exit(0);
+}
+
+init()
+{
+       register i, c;
+       register char *cp;
+       register char *ocp;
+       register int n;
+
+       freopen(crontab, "r", stdin);
+       if (list) {
+               free(list);
+               list = realloc(list, LISTS);
+       } else
+               list = malloc(LISTS);
+       listsize = LISTS;
+       cp = list;
+
+loop:
+       if(cp > list+listsize-100) {
+               char *olist;
+               listsize += LISTS;
+               olist = list;
+               free(list);
+               list = realloc(list, listsize);
+               cp = list + (cp - olist);
+       }
+       ocp = cp;
+       for(i=0;; i++) {
+               do
+                       c = getchar();
+               while(c == ' ' || c == '\t')
+                       ;
+               if(c == EOF || c == '\n')
+                       goto ignore;
+               if(i == 5)
+                       break;
+               if(c == '*') {
+                       *cp++ = ANY;
+                       continue;
+               }
+               if ((n = number(c)) < 0)
+                       goto ignore;
+               c = getchar();
+               if(c == ',')
+                       goto mlist;
+               if(c == '-')
+                       goto mrange;
+               if(c != '\t' && c != ' ')
+                       goto ignore;
+               *cp++ = EXACT;
+               *cp++ = n;
+               continue;
+
+       mlist:
+               *cp++ = LIST;
+               *cp++ = n;
+               do {
+                       if ((n = number(getchar())) < 0)
+                               goto ignore;
+                       *cp++ = n;
+                       c = getchar();
+               } while (c==',');
+               if(c != '\t' && c != ' ')
+                       goto ignore;
+               *cp++ = LIST;
+               continue;
+
+       mrange:
+               *cp++ = RANGE;
+               *cp++ = n;
+               if ((n = number(getchar())) < 0)
+                       goto ignore;
+               c = getchar();
+               if(c != '\t' && c != ' ')
+                       goto ignore;
+               *cp++ = n;
+       }
+       while(c != '\n') {
+               if(c == EOF)
+                       goto ignore;
+               if(c == '%')
+                       c = '\n';
+               *cp++ = c;
+               c = getchar();
+       }
+       *cp++ = '\n';
+       *cp++ = 0;
+       goto loop;
+
+ignore:
+       cp = ocp;
+       while(c != '\n') {
+               if(c == EOF) {
+                       *cp++ = EOS;
+                       *cp++ = EOS;
+                       fclose(stdin);
+                       return;
+               }
+               c = getchar();
+       }
+       goto loop;
+}
+
+number(c)
+register c;
+{
+       register n = 0;
+
+       while (isdigit(c)) {
+               n = n*10 + c - '0';
+               c = getchar();
+       }
+       ungetc(c, stdin);
+       if (n>100)
+               return(-1);
+       return(n);
+}
diff --git a/usr/src/cmd/crypt.c b/usr/src/cmd/crypt.c
new file mode 100644 (file)
index 0000000..b53e451
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *     A one-rotor machine designed along the lines of Enigma
+ *     but considerably trivialized.
+ */
+
+#define ECHO 010
+#include <stdio.h>
+#define ROTORSZ 256
+#define MASK 0377
+char   t1[ROTORSZ];
+char   t2[ROTORSZ];
+char   t3[ROTORSZ];
+char   *getpass();
+
+setup(pw)
+char *pw;
+{
+       int ic, i, k, temp, pf[2];
+       unsigned random;
+       char buf[13];
+       long seed;
+
+       strncpy(buf, pw, 8);
+       while (*pw)
+               *pw++ = '\0';
+       buf[8] = buf[0];
+       buf[9] = buf[1];
+       pipe(pf);
+       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);
+       wait((int *)NULL);
+       if (read(pf[0], buf, 13) != 13) {
+               fprintf(stderr, "crypt: cannot generate key\n");
+               exit(1);
+       }
+       seed = 123;
+       for (i=0; i<13; i++)
+               seed = seed*buf[i] + i;
+       for(i=0;i<ROTORSZ;i++)
+               t1[i] = i;
+       for(i=0;i<ROTORSZ;i++) {
+               seed = 5*seed + buf[i%13];
+               random = seed % 65521;
+               k = ROTORSZ-1 - i;
+               ic = (random&MASK)%(k+1);
+               random >>= 8;
+               temp = t1[k];
+               t1[k] = t1[ic];
+               t1[ic] = temp;
+               if(t3[k]!=0) continue;
+               ic = (random&MASK) % k;
+               while(t3[ic]!=0) ic = (ic+1) % k;
+               t3[k] = ic;
+               t3[ic] = k;
+       }
+       for(i=0;i<ROTORSZ;i++)
+               t2[t1[i]&MASK] = i;
+}
+
+main(argc, argv)
+char *argv[];
+{
+       register i, n1, n2;
+
+       if (argc != 2){
+               setup(getpass("Enter key:"));
+       }
+       else
+               setup(argv[1]);
+       n1 = 0;
+       n2 = 0;
+
+       while((i=getchar()) >=0) {
+               i = t2[(t3[(t1[(i+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1;
+               putchar(i);
+               n1++;
+               if(n1==ROTORSZ) {
+                       n1 = 0;
+                       n2++;
+                       if(n2==ROTORSZ) n2 = 0;
+               }
+       }
+}
diff --git a/usr/src/cmd/date.c b/usr/src/cmd/date.c
new file mode 100644 (file)
index 0000000..a005765
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * date : print date
+ * date YYMMDDHHMM[.SS] : set date, if allowed
+ * date -u ... : date in GMT
+ */
+#include <time.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+#include <utmp.h>
+long   timbuf;
+char   *ap, *ep, *sp;
+int    uflag;
+
+char   *timezone();
+static int     dmsize[12] =
+{
+       31,
+       28,
+       31,
+       30,
+       31,
+       30,
+       31,
+       31,
+       30,
+       31,
+       30,
+       31
+};
+
+struct utmp wtmp[2] = { {"|", "", 0}, {"{", "", 0}};
+
+char   *ctime();
+char   *asctime();
+struct tm *localtime();
+struct tm *gmtime();
+
+main(argc, argv)
+char *argv[];
+{
+       register char *tzn;
+       struct timeb info;
+       int wf, rc;
+
+       rc = 0;
+       ftime(&info);
+       if (argc>1 && argv[1][0]=='-' && argv[1][1]=='u') {
+               argc--;
+               argv++;
+               uflag++;
+       }
+       if(argc > 1) {
+               ap = argv[1];
+               if (gtime()) {
+                       printf("date: bad conversion\n");
+                       exit(1);
+               }
+               /* convert to GMT assuming local time */
+               if (uflag==0) {
+                       timbuf += (long)info.timezone*60;
+                       /* now fix up local daylight time */
+                       if(localtime(&timbuf)->tm_isdst)
+                               timbuf -= 60*60;
+               }
+               time(&wtmp[0].ut_time);
+               if(stime(&timbuf) < 0) {
+                       rc++;
+                       printf("date: no permission\n");
+               } else if ((wf = open("/usr/adm/wtmp", 1)) >= 0) {
+                       time(&wtmp[1].ut_time);
+                       lseek(wf, 0L, 2);
+                       write(wf, (char *)wtmp, sizeof(wtmp));
+                       close(wf);
+               }
+       }
+       if (rc==0)
+               time(&timbuf);
+       if(uflag) {
+               ap = asctime(gmtime(&timbuf));
+               tzn = "GMT";
+       } else {
+               struct tm *tp;
+               tp = localtime(&timbuf);
+               ap = asctime(tp);
+               tzn = timezone(info.timezone, tp->tm_isdst);
+       }
+       printf("%.20s", ap);
+       if (tzn)
+               printf("%s", tzn);
+       printf("%s", ap+19);
+       exit(rc);
+}
+
+gtime()
+{
+       register int i, year, month;
+       int day, hour, mins, secs;
+       struct tm *L;
+       char x;
+
+       ep=ap;
+       while(*ep) ep++;
+       sp=ap;
+       while(sp<ep) {
+               x = *sp;
+               *sp++ = *--ep;
+               *ep = x;
+       }
+       sp=ap;
+       time(&timbuf);
+       L=localtime(&timbuf);
+       secs = gp(-1);
+       if(*sp!='.') {
+               mins=secs;
+               secs=0;
+       } else {sp++;
+               mins = gp(-1);
+       }
+       hour = gp(-1);
+       day = gp(L->tm_mday);
+       month = gp(L->tm_mon+1);
+       year = gp(L->tm_year);
+       if(*sp)
+               return(1);
+       if( month<1 || month>12 ||
+           day<1 || day>31 ||
+           mins<0 || mins>59 ||
+           secs<0 || secs>59)
+               return(1);
+       if (hour==24) {
+               hour=0; day++;
+       }
+       if (hour<0 || hour>23)
+               return(1);
+       timbuf = 0;
+       year += 1900;
+       for(i=1970; i<year; i++)
+               timbuf += dysize(i);
+       /* Leap year */
+       if (dysize(year)==366 && month >= 3)
+               timbuf++;
+       while(--month)
+               timbuf += dmsize[month-1];
+       timbuf += day-1;
+       timbuf = 24*timbuf + hour;
+       timbuf = 60*timbuf + mins;
+       timbuf = 60*timbuf + secs;
+       return(0);
+
+}
+
+gp(dfault)
+{
+       register int c, d;
+
+       if(*sp==0)
+               return(dfault);
+       c = (*sp++)-'0';
+       d = (*sp ? (*sp++)-'0' : 0);
+       if(c<0 || c>9 || d<0 || d>9)
+               return(-1);
+       return(c+10*d);
+}
diff --git a/usr/src/cmd/dd.c b/usr/src/cmd/dd.c
new file mode 100644 (file)
index 0000000..85d5c03
--- /dev/null
@@ -0,0 +1,541 @@
+#include <stdio.h>
+#include <signal.h>
+
+#define        BIG     2147483647
+#define        LCASE   01
+#define        UCASE   02
+#define        SWAB    04
+#define NERR   010
+#define SYNC   020
+int    cflag;
+int    fflag;
+int    skip;
+int    seekn;
+int    count;
+int    files   = 1;
+char   *string;
+char   *ifile;
+char   *ofile;
+char   *ibuf;
+char   *obuf;
+char   *sbrk();
+int    ibs     = 512;
+int    obs     = 512;
+int    bs;
+int    cbs;
+int    ibc;
+int    obc;
+int    cbc;
+int    nifr;
+int    nipr;
+int    nofr;
+int    nopr;
+int    ntrunc;
+int    ibf;
+int    obf;
+char   *op;
+int    nspace;
+char   etoa[] = {
+       0000,0001,0002,0003,0234,0011,0206,0177,
+       0227,0215,0216,0013,0014,0015,0016,0017,
+       0020,0021,0022,0023,0235,0205,0010,0207,
+       0030,0031,0222,0217,0034,0035,0036,0037,
+       0200,0201,0202,0203,0204,0012,0027,0033,
+       0210,0211,0212,0213,0214,0005,0006,0007,
+       0220,0221,0026,0223,0224,0225,0226,0004,
+       0230,0231,0232,0233,0024,0025,0236,0032,
+       0040,0240,0241,0242,0243,0244,0245,0246,
+       0247,0250,0133,0056,0074,0050,0053,0041,
+       0046,0251,0252,0253,0254,0255,0256,0257,
+       0260,0261,0135,0044,0052,0051,0073,0136,
+       0055,0057,0262,0263,0264,0265,0266,0267,
+       0270,0271,0174,0054,0045,0137,0076,0077,
+       0272,0273,0274,0275,0276,0277,0300,0301,
+       0302,0140,0072,0043,0100,0047,0075,0042,
+       0303,0141,0142,0143,0144,0145,0146,0147,
+       0150,0151,0304,0305,0306,0307,0310,0311,
+       0312,0152,0153,0154,0155,0156,0157,0160,
+       0161,0162,0313,0314,0315,0316,0317,0320,
+       0321,0176,0163,0164,0165,0166,0167,0170,
+       0171,0172,0322,0323,0324,0325,0326,0327,
+       0330,0331,0332,0333,0334,0335,0336,0337,
+       0340,0341,0342,0343,0344,0345,0346,0347,
+       0173,0101,0102,0103,0104,0105,0106,0107,
+       0110,0111,0350,0351,0352,0353,0354,0355,
+       0175,0112,0113,0114,0115,0116,0117,0120,
+       0121,0122,0356,0357,0360,0361,0362,0363,
+       0134,0237,0123,0124,0125,0126,0127,0130,
+       0131,0132,0364,0365,0366,0367,0370,0371,
+       0060,0061,0062,0063,0064,0065,0066,0067,
+       0070,0071,0372,0373,0374,0375,0376,0377,
+};
+char   atoe[] = {
+       0000,0001,0002,0003,0067,0055,0056,0057,
+       0026,0005,0045,0013,0014,0015,0016,0017,
+       0020,0021,0022,0023,0074,0075,0062,0046,
+       0030,0031,0077,0047,0034,0035,0036,0037,
+       0100,0117,0177,0173,0133,0154,0120,0175,
+       0115,0135,0134,0116,0153,0140,0113,0141,
+       0360,0361,0362,0363,0364,0365,0366,0367,
+       0370,0371,0172,0136,0114,0176,0156,0157,
+       0174,0301,0302,0303,0304,0305,0306,0307,
+       0310,0311,0321,0322,0323,0324,0325,0326,
+       0327,0330,0331,0342,0343,0344,0345,0346,
+       0347,0350,0351,0112,0340,0132,0137,0155,
+       0171,0201,0202,0203,0204,0205,0206,0207,
+       0210,0211,0221,0222,0223,0224,0225,0226,
+       0227,0230,0231,0242,0243,0244,0245,0246,
+       0247,0250,0251,0300,0152,0320,0241,0007,
+       0040,0041,0042,0043,0044,0025,0006,0027,
+       0050,0051,0052,0053,0054,0011,0012,0033,
+       0060,0061,0032,0063,0064,0065,0066,0010,
+       0070,0071,0072,0073,0004,0024,0076,0341,
+       0101,0102,0103,0104,0105,0106,0107,0110,
+       0111,0121,0122,0123,0124,0125,0126,0127,
+       0130,0131,0142,0143,0144,0145,0146,0147,
+       0150,0151,0160,0161,0162,0163,0164,0165,
+       0166,0167,0170,0200,0212,0213,0214,0215,
+       0216,0217,0220,0232,0233,0234,0235,0236,
+       0237,0240,0252,0253,0254,0255,0256,0257,
+       0260,0261,0262,0263,0264,0265,0266,0267,
+       0270,0271,0272,0273,0274,0275,0276,0277,
+       0312,0313,0314,0315,0316,0317,0332,0333,
+       0334,0335,0336,0337,0352,0353,0354,0355,
+       0356,0357,0372,0373,0374,0375,0376,0377,
+};
+char   atoibm[] =
+{
+       0000,0001,0002,0003,0067,0055,0056,0057,
+       0026,0005,0045,0013,0014,0015,0016,0017,
+       0020,0021,0022,0023,0074,0075,0062,0046,
+       0030,0031,0077,0047,0034,0035,0036,0037,
+       0100,0132,0177,0173,0133,0154,0120,0175,
+       0115,0135,0134,0116,0153,0140,0113,0141,
+       0360,0361,0362,0363,0364,0365,0366,0367,
+       0370,0371,0172,0136,0114,0176,0156,0157,
+       0174,0301,0302,0303,0304,0305,0306,0307,
+       0310,0311,0321,0322,0323,0324,0325,0326,
+       0327,0330,0331,0342,0343,0344,0345,0346,
+       0347,0350,0351,0255,0340,0275,0137,0155,
+       0171,0201,0202,0203,0204,0205,0206,0207,
+       0210,0211,0221,0222,0223,0224,0225,0226,
+       0227,0230,0231,0242,0243,0244,0245,0246,
+       0247,0250,0251,0300,0117,0320,0241,0007,
+       0040,0041,0042,0043,0044,0025,0006,0027,
+       0050,0051,0052,0053,0054,0011,0012,0033,
+       0060,0061,0032,0063,0064,0065,0066,0010,
+       0070,0071,0072,0073,0004,0024,0076,0341,
+       0101,0102,0103,0104,0105,0106,0107,0110,
+       0111,0121,0122,0123,0124,0125,0126,0127,
+       0130,0131,0142,0143,0144,0145,0146,0147,
+       0150,0151,0160,0161,0162,0163,0164,0165,
+       0166,0167,0170,0200,0212,0213,0214,0215,
+       0216,0217,0220,0232,0233,0234,0235,0236,
+       0237,0240,0252,0253,0254,0255,0256,0257,
+       0260,0261,0262,0263,0264,0265,0266,0267,
+       0270,0271,0272,0273,0274,0275,0276,0277,
+       0312,0313,0314,0315,0316,0317,0332,0333,
+       0334,0335,0336,0337,0352,0353,0354,0355,
+       0356,0357,0372,0373,0374,0375,0376,0377,
+};
+
+
+main(argc, argv)
+int    argc;
+char   **argv;
+{
+       int (*conv)();
+       register char *ip;
+       register c;
+       int ebcdic(), ibm(), ascii(), null(), cnull(), term();
+       int a;
+
+       conv = null;
+       for(c=1; c<argc; c++) {
+               string = argv[c];
+               if(match("ibs=")) {
+                       ibs = number(BIG);
+                       continue;
+               }
+               if(match("obs=")) {
+                       obs = number(BIG);
+                       continue;
+               }
+               if(match("cbs=")) {
+                       cbs = number(BIG);
+                       continue;
+               }
+               if (match("bs=")) {
+                       bs = number(BIG);
+                       continue;
+               }
+               if(match("if=")) {
+                       ifile = string;
+                       continue;
+               }
+               if(match("of=")) {
+                       ofile = string;
+                       continue;
+               }
+               if(match("skip=")) {
+                       skip = number(BIG);
+                       continue;
+               }
+               if(match("seek=")) {
+                       seekn = number(BIG);
+                       continue;
+               }
+               if(match("count=")) {
+                       count = number(BIG);
+                       continue;
+               }
+               if(match("files=")) {
+                       files = number(BIG);
+                       continue;
+               }
+               if(match("conv=")) {
+               cloop:
+                       if(match(","))
+                               goto cloop;
+                       if(*string == '\0')
+                               continue;
+                       if(match("ebcdic")) {
+                               conv = ebcdic;
+                               goto cloop;
+                       }
+                       if(match("ibm")) {
+                               conv = ibm;
+                               goto cloop;
+                       }
+                       if(match("ascii")) {
+                               conv = ascii;
+                               goto cloop;
+                       }
+                       if(match("lcase")) {
+                               cflag |= LCASE;
+                               goto cloop;
+                       }
+                       if(match("ucase")) {
+                               cflag |= UCASE;
+                               goto cloop;
+                       }
+                       if(match("swab")) {
+                               cflag |= SWAB;
+                               goto cloop;
+                       }
+                       if(match("noerror")) {
+                               cflag |= NERR;
+                               goto cloop;
+                       }
+                       if(match("sync")) {
+                               cflag |= SYNC;
+                               goto cloop;
+                       }
+               }
+               fprintf(stderr,"bad arg: %s\n", string);
+               exit(0);
+       }
+       if(conv == null && cflag&(LCASE|UCASE))
+               conv = cnull;
+       if (ifile)
+               ibf = open(ifile, 0);
+       else
+               ibf = dup(0);
+       if(ibf < 0) {
+               fprintf(stderr,"cannot open: %s\n", ifile);
+               exit(0);
+       }
+       if (ofile)
+               obf = creat(ofile, 0666);
+       else
+               obf = dup(1);
+       if(obf < 0) {
+               fprintf(stderr,"cannot create: %s\n", ofile);
+               exit(0);
+       }
+       if (bs) {
+               ibs = obs = bs;
+               if (conv == null)
+                       fflag++;
+       }
+       if(ibs == 0 || obs == 0) {
+               fprintf(stderr,"counts: cannot be zero\n");
+               exit(0);
+       }
+       ibuf = sbrk(ibs);
+       if (fflag)
+               obuf = ibuf;
+       else
+               obuf = sbrk(obs);
+       sbrk(64);       /* For good measure */
+       if(ibuf == (char *)-1 || obuf == (char *)-1) {
+               fprintf(stderr, "not enough memory\n");
+               exit(0);
+       }
+       ibc = 0;
+       obc = 0;
+       cbc = 0;
+       op = obuf;
+
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, term);
+       while(skip) {
+               read(ibf, ibuf, ibs);
+               skip--;
+       }
+       while(seekn) {
+               lseek(obf, (long)obs, 1);
+               seekn--;
+       }
+
+loop:
+       if(ibc-- == 0) {
+               ibc = 0;
+               if(count==0 || nifr+nipr!=count) {
+                       if(cflag&(NERR|SYNC))
+                       for(ip=ibuf+ibs; ip>ibuf;)
+                               *--ip = 0;
+                       ibc = read(ibf, ibuf, ibs);
+               }
+               if(ibc == -1) {
+                       perror("read");
+                       if((cflag&NERR) == 0) {
+                               flsh();
+                               term();
+                       }
+                       ibc = 0;
+                       for(c=0; c<ibs; c++)
+                               if(ibuf[c] != 0)
+                                       ibc = c;
+                       stats();
+               }
+               if(ibc == 0 && --files<=0) {
+                       flsh();
+                       term();
+               }
+               if(ibc != ibs) {
+                       nipr++;
+                       if(cflag&SYNC)
+                               ibc = ibs;
+               } else
+                       nifr++;
+               ip = ibuf;
+               c = (ibc>>1) & ~1;
+               if(cflag&SWAB && c)
+               do {
+                       a = *ip++;
+                       ip[-1] = *ip;
+                       *ip++ = a;
+               } while(--c);
+               ip = ibuf;
+               if (fflag) {
+                       obc = ibc;
+                       flsh();
+                       ibc = 0;
+               }
+               goto loop;
+       }
+       c = 0;
+       c |= *ip++;
+       c &= 0377;
+       (*conv)(c);
+       goto loop;
+}
+
+flsh()
+{
+       register c;
+
+       if(obc) {
+               if(obc == obs)
+                       nofr++; else
+                       nopr++;
+               c = write(obf, obuf, obc);
+               if(c != obc) {
+                       perror("write");
+                       term();
+               }
+               obc = 0;
+       }
+}
+
+match(s)
+char *s;
+{
+       register char *cs;
+
+       cs = string;
+       while(*cs++ == *s)
+               if(*s++ == '\0')
+                       goto true;
+       if(*s != '\0')
+               return(0);
+
+true:
+       cs--;
+       string = cs;
+       return(1);
+}
+
+number(big)
+{
+       register char *cs;
+       long n;
+
+       cs = string;
+       n = 0;
+       while(*cs >= '0' && *cs <= '9')
+               n = n*10 + *cs++ - '0';
+       for(;;)
+       switch(*cs++) {
+
+       case 'k':
+               n *= 1024;
+               continue;
+
+       case 'w':
+               n *= sizeof(int);
+               continue;
+
+       case 'b':
+               n *= 512;
+               continue;
+
+       case '*':
+       case 'x':
+               string = cs;
+               n *= number(BIG);
+
+       case '\0':
+               if (n>=big || n<0) {
+                       fprintf(stderr, "dd: argument %D out of range\n", n);
+                       exit(1);
+               }
+               return(n);
+       }
+       /* never gets here */
+}
+
+cnull(cc)
+{
+       register c;
+
+       c = cc;
+       if(cflag&UCASE && c>='a' && c<='z')
+               c += 'A'-'a';
+       if(cflag&LCASE && c>='A' && c<='Z')
+               c += 'a'-'A';
+       null(c);
+}
+
+null(c)
+{
+
+       *op = c;
+       op++;
+       if(++obc >= obs) {
+               flsh();
+               op = obuf;
+       }
+}
+
+ascii(cc)
+{
+       register c;
+
+       c = etoa[cc] & 0377;
+       if(cbs == 0) {
+               cnull(c);
+               return;
+       }
+       if(c == ' ') {
+               nspace++;
+               goto out;
+       }
+       while(nspace > 0) {
+               null(' ');
+               nspace--;
+       }
+       cnull(c);
+
+out:
+       if(++cbc >= cbs) {
+               null('\n');
+               cbc = 0;
+               nspace = 0;
+       }
+}
+
+ebcdic(cc)
+{
+       register c;
+
+       c = cc;
+       if(cflag&UCASE && c>='a' && c<='z')
+               c += 'A'-'a';
+       if(cflag&LCASE && c>='A' && c<='Z')
+               c += 'a'-'A';
+       c = atoe[c] & 0377;
+       if(cbs == 0) {
+               null(c);
+               return;
+       }
+       if(cc == '\n') {
+               while(cbc < cbs) {
+                       null(atoe[' ']);
+                       cbc++;
+               }
+               cbc = 0;
+               return;
+       }
+       if(cbc == cbs)
+               ntrunc++;
+       cbc++;
+       if(cbc <= cbs)
+               null(c);
+}
+
+ibm(cc)
+{
+       register c;
+
+       c = cc;
+       if(cflag&UCASE && c>='a' && c<='z')
+               c += 'A'-'a';
+       if(cflag&LCASE && c>='A' && c<='Z')
+               c += 'a'-'A';
+       c = atoibm[c] & 0377;
+       if(cbs == 0) {
+               null(c);
+               return;
+       }
+       if(cc == '\n') {
+               while(cbc < cbs) {
+                       null(atoibm[' ']);
+                       cbc++;
+               }
+               cbc = 0;
+               return;
+       }
+       if(cbc == cbs)
+               ntrunc++;
+       cbc++;
+       if(cbc <= cbs)
+               null(c);
+}
+
+term()
+{
+
+       stats();
+       exit(0);
+}
+
+stats()
+{
+
+       fprintf(stderr,"%u+%u records in\n", nifr, nipr);
+       fprintf(stderr,"%u+%u records out\n", nofr, nopr);
+       if(ntrunc)
+               fprintf(stderr,"%u truncated records\n", ntrunc);
+}
diff --git a/usr/src/cmd/diffh.c b/usr/src/cmd/diffh.c
new file mode 100644 (file)
index 0000000..2fb37c8
--- /dev/null
@@ -0,0 +1,262 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define C 3
+#define RANGE 30
+#define LEN 255
+#define INF 16384
+
+char *text[2][RANGE];
+long lineno[2] = {1, 1};       /*no. of 1st stored line in each file*/
+int ntext[2];          /*number of stored lines in each*/
+long n0,n1;            /*scan pointer in each*/
+int bflag;
+int debug = 0;
+FILE *file[2];
+
+       /* return pointer to line n of file f*/
+char *getl(f,n)
+long n;
+{
+       register char *t;
+       char *malloc();
+       register delta, nt;
+again:
+       delta = n - lineno[f];
+       nt = ntext[f];
+       if(delta<0)
+               progerr("1");
+       if(delta<nt)
+               return(text[f][delta]);
+       if(delta>nt)
+               progerr("2");
+       if(nt>=RANGE)
+               progerr("3");
+       if(feof(file[f]))
+               return(NULL);
+       t = text[f][nt];
+       if(t==0) {
+               t = text[f][nt] = malloc(LEN+1);
+               if(t==NULL)
+                       if(hardsynch())
+                               goto again;
+                       else
+                               progerr("5");
+       }
+       t = fgets(t,LEN,file[f]);
+       if(t!=NULL)
+               ntext[f]++;
+       return(t);
+}
+
+       /*remove thru line n of file f from storage*/
+clrl(f,n)
+long n;
+{
+       register i,j;
+       j = n-lineno[f]+1;
+       for(i=0;i+j<ntext[f];i++)
+               movstr(text[f][i+j],text[f][i]);
+       lineno[f] = n+1;
+       ntext[f] -= j;
+}
+
+movstr(s,t)
+register char *s, *t;
+{
+       while(*t++= *s++)
+               continue;
+}
+
+main(argc,argv)
+char **argv;
+{
+       char *s0,*s1;
+       FILE *dopen();
+       if(*argv[1]=='-') {
+               argc--;
+               argv++;
+               while(*++argv[0])
+                       if(*argv[0]=='b')
+                               bflag++;
+       }
+       if(argc!=3)
+               error("must have 2 file arguments","");
+       file[0] = dopen(argv[1],argv[2]);
+       file[1] = dopen(argv[2],argv[1]);
+       for(;;) {
+               s0 = getl(0,++n0);
+               s1 = getl(1,++n1);
+               if(s0==NULL||s1==NULL)
+                       break;
+               if(cmp(s0,s1)!=0) {
+                       if(!easysynch()&&!hardsynch())
+                               progerr("5");
+               } else {
+                       clrl(0,n0);
+                       clrl(1,n1);
+               }
+       }
+       if(s0==NULL&&s1==NULL)
+               return;
+       if(s0==NULL)
+               output(-1,INF);
+       if(s1==NULL)
+               output(INF,-1);
+}
+
+       /* synch on C successive matches*/
+easysynch()
+{
+       int i,j;
+       register k,m;
+       char *s0,*s1;
+       for(i=j=1;i<RANGE&&j<RANGE;i++,j++) {
+               s0 = getl(0,n0+i);
+               if(s0==NULL)
+                       return(output(INF,INF));
+               for(k=C-1;k<j;k++) {
+                       for(m=0;m<C;m++)
+                               if(cmp(getl(0,n0+i-m),
+                                       getl(1,n1+k-m))!=0)
+                                       goto cont1;
+                       return(output(i-C,k-C));
+cont1:                 ;
+               }
+               s1 = getl(1,n1+j);
+               if(s1==NULL)
+                       return(output(INF,INF));
+               for(k=C-1;k<=i;k++) {
+                       for(m=0;m<C;m++)
+                               if(cmp(getl(0,n0+k-m),
+                                       getl(1,n1+j-m))!=0)
+                                       goto cont2;
+                       return(output(k-C,j-C));
+cont2:                 ;
+               }
+       }
+       return(0);
+}
+
+output(a,b)
+{
+       register i;
+       char *s;
+       if(a<0)
+               change(n0-1,0,n1,b,"a");
+       else if(b<0)
+               change(n0,a,n1-1,0,"d");
+       else
+               change(n0,a,n1,b,"c");
+       for(i=0;i<=a;i++) {
+               s = getl(0,n0+i);
+               if(s==NULL)
+                       break;
+               printf("< %s",s);
+               clrl(0,n0+i);
+       }
+       n0 += i-1;
+       if(a>=0&&b>=0)
+               printf("---\n");
+       for(i=0;i<=b;i++) {
+               s = getl(1,n1+i);
+               if(s==NULL)
+                       break;
+               printf("> %s",s);
+               clrl(1,n1+i);
+       }
+       n1 += i-1;
+       return(1);
+}
+
+change(a,b,c,d,s)
+long a,c;
+char *s;
+{
+       range(a,b);
+       printf("%s",s);
+       range(c,d);
+       printf("\n");
+}
+
+range(a,b)
+long a;
+{
+       if(b==INF)
+               printf("%ld,$",a);
+       else if(b==0)
+               printf("%ld",a);
+       else
+               printf("%ld,%ld",a,a+b);
+}
+
+cmp(s,t)
+char *s,*t;
+{
+       if(debug)
+               printf("%s:%s\n",s,t);
+       for(;;){
+               if(bflag&&isspace(*s)&&isspace(*t)) {
+                       while(isspace(*++s)) ;
+                       while(isspace(*++t)) ;
+               }
+               if(*s!=*t||*s==0)
+                       break;
+               s++;
+               t++;
+       }
+       return(*s-*t);
+}
+
+FILE *dopen(f1,f2)
+char *f1,*f2;
+{
+       FILE *f;
+       char b[100],*bptr,*eptr;
+       struct stat statbuf;
+       if(cmp(f1,"-")==0)
+               if(cmp(f2,"-")==0)
+                       error("can't do - -","");
+               else
+                       return(stdin);
+       if(stat(f1,&statbuf)==-1)
+               error("can't access ",f1);
+       if((statbuf.st_mode&S_IFMT)==S_IFDIR) {
+               for(bptr=b;*bptr= *f1++;bptr++) ;
+               *bptr++ = '/';
+               for(eptr=f2;*eptr;eptr++)
+                       if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/')
+                               f2 = eptr+1;
+               while(*bptr++= *f2++) ;
+               f1 = b;
+       }
+       f = fopen(f1,"r");
+       if(f==NULL)
+               error("can't open",f1);
+       return(f);
+}
+
+
+progerr(s)
+char *s;
+{
+       error("program error ",s);
+}
+
+error(s,t)
+char *s,*t;
+{
+       fprintf(stderr,"diffh: %s%s\n",s,t);
+       exit(1);
+}
+
+       /*stub for resychronization beyond limits of text buf*/
+hardsynch()
+{
+       change(n0,INF,n1,INF,"c");
+       printf("---change record omitted\n");
+       error("can't resynchronize","");
+       return(0);
+}
diff --git a/usr/src/cmd/echo.c b/usr/src/cmd/echo.c
new file mode 100644 (file)
index 0000000..c9ee03c
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       register int i, nflg;
+
+       nflg = 0;
+       if(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n') {
+               nflg++;
+               argc--;
+               argv++;
+       }
+       for(i=1; i<argc; i++) {
+               fputs(argv[i], stdout);
+               if (i < argc-1)
+                       putchar(' ');
+       }
+       if(nflg == 0)
+               putchar('\n');
+       exit(0);
+}
diff --git a/usr/src/cmd/ed/ed.c b/usr/src/cmd/ed/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/egrep.y b/usr/src/cmd/egrep.y
new file mode 100644 (file)
index 0000000..22de9fd
--- /dev/null
@@ -0,0 +1,590 @@
+/*
+ * egrep -- print lines containing (or not containing) a regular expression
+ *
+ *     status returns:
+ *             0 - ok, and some matches
+ *             1 - ok, but no matches
+ *             2 - some error
+ */
+%token CHAR DOT CCL NCCL OR CAT STAR PLUS QUEST
+%left OR
+%left CHAR DOT CCL NCCL '('
+%left CAT
+%left STAR PLUS QUEST
+
+%{
+#include <stdio.h>
+
+#define MAXLIN 350
+#define MAXPOS 4000
+#define NCHARS 128
+#define NSTATES 128
+#define FINAL -1
+char gotofn[NSTATES][NCHARS];
+int state[NSTATES];
+char out[NSTATES];
+int line = 1;
+int name[MAXLIN];
+int left[MAXLIN];
+int right[MAXLIN];
+int parent[MAXLIN];
+int foll[MAXLIN];
+int positions[MAXPOS];
+char chars[MAXLIN];
+int nxtpos;
+int nxtchar = 0;
+int tmpstat[MAXLIN];
+int initstat[MAXLIN];
+int xstate;
+int count;
+int icount;
+char *input;
+
+long   lnum;
+int    bflag;
+int    cflag;
+int    fflag;
+int    lflag;
+int    nflag;
+int    hflag   = 1;
+int    sflag;
+int    vflag;
+int    nfile;
+int    blkno;
+long   tln;
+int    nsucc;
+
+int    f;
+int    fname;
+%}
+
+%%
+s:     t
+               ={ unary(FINAL, $1);
+                 line--;
+               }
+       ;
+t:     b r
+               ={ $$ = node(CAT, $1, $2); }
+       | OR b r OR
+               ={ $$ = node(CAT, $2, $3); }
+       | OR b r
+               ={ $$ = node(CAT, $2, $3); }
+       | b r OR
+               ={ $$ = node(CAT, $1, $2); }
+       ;
+b:
+               ={ $$ = enter(DOT);
+                  $$ = unary(STAR, $$); }
+       ;
+r:     CHAR
+               ={ $$ = enter($1); }
+       | DOT
+               ={ $$ = enter(DOT); }
+       | CCL
+               ={ $$ = cclenter(CCL); }
+       | NCCL
+               ={ $$ = cclenter(NCCL); }
+       ;
+
+r:     r OR r
+               ={ $$ = node(OR, $1, $3); }
+       | r r %prec CAT
+               ={ $$ = node(CAT, $1, $2); }
+       | r STAR
+               ={ $$ = unary(STAR, $1); }
+       | r PLUS
+               ={ $$ = unary(PLUS, $1); }
+       | r QUEST
+               ={ $$ = unary(QUEST, $1); }
+       | '(' r ')'
+               ={ $$ = $2; }
+       | error 
+       ;
+
+%%
+yyerror(s) {
+       fprintf(stderr, "egrep: %s\n", s);
+       exit(2);
+}
+
+yylex() {
+       extern int yylval;
+       int cclcnt, x;
+       register char c, d;
+       switch(c = nextch()) {
+               case '$':
+               case '^': c = '\n';
+                       goto defchar;
+               case '|': return (OR);
+               case '*': return (STAR);
+               case '+': return (PLUS);
+               case '?': return (QUEST);
+               case '(': return (c);
+               case ')': return (c);
+               case '.': return (DOT);
+               case '\0': return (0);
+               case '\n': return (OR);
+               case '[': 
+                       x = CCL;
+                       cclcnt = 0;
+                       count = nxtchar++;
+                       if ((c = nextch()) == '^') {
+                               x = NCCL;
+                               c = nextch();
+                       }
+                       do {
+                               if (c == '\0') synerror();
+                               if (c == '-' && cclcnt > 0 && chars[nxtchar-1] != 0) {
+                                       if ((d = nextch()) != 0) {
+                                               c = chars[nxtchar-1];
+                                               while (c < d) {
+                                                       if (nxtchar >= MAXLIN) overflo();
+                                                       chars[nxtchar++] = ++c;
+                                                       cclcnt++;
+                                               }
+                                               continue;
+                                       }
+                               }
+                               if (nxtchar >= MAXLIN) overflo();
+                               chars[nxtchar++] = c;
+                               cclcnt++;
+                       } while ((c = nextch()) != ']');
+                       chars[count] = cclcnt;
+                       return (x);
+               case '\\':
+                       if ((c = nextch()) == '\0') synerror();
+               defchar:
+               default: yylval = c; return (CHAR);
+       }
+}
+nextch() {
+       register char c;
+       if (fflag) {
+               if ((c = getc(stdin)) == EOF) return(0);
+       }
+       else c = *input++;
+       return(c);
+}
+
+synerror() {
+       fprintf(stderr, "egrep: syntax error\n");
+       exit(2);
+}
+
+enter(x) int x; {
+       if(line >= MAXLIN) overflo();
+       name[line] = x;
+       left[line] = 0;
+       right[line] = 0;
+       return(line++);
+}
+
+cclenter(x) int x; {
+       register linno;
+       linno = enter(x);
+       right[linno] = count;
+       return (linno);
+}
+
+node(x, l, r) {
+       if(line >= MAXLIN) overflo();
+       name[line] = x;
+       left[line] = l;
+       right[line] = r;
+       parent[l] = line;
+       parent[r] = line;
+       return(line++);
+}
+
+unary(x, d) {
+       if(line >= MAXLIN) overflo();
+       name[line] = x;
+       left[line] = d;
+       right[line] = 0;
+       parent[d] = line;
+       return(line++);
+}
+overflo() {
+       fprintf(stderr, "egrep: regular expression too long\n");
+       exit(2);
+}
+
+cfoll(v) {
+       register i;
+       if (left[v] == 0) {
+               count = 0;
+               for (i=1; i<=line; i++) tmpstat[i] = 0;
+               follow(v);
+               add(foll, v);
+       }
+       else if (right[v] == 0) cfoll(left[v]);
+       else {
+               cfoll(left[v]);
+               cfoll(right[v]);
+       }
+}
+cgotofn() {
+       register c, i, k;
+       int n, s;
+       char symbol[NCHARS];
+       int j, nc, pc, pos;
+       int curpos, num;
+       int number, newpos;
+       count = 0;
+       for (n=3; n<=line; n++) tmpstat[n] = 0;
+       if (cstate(line-1)==0) {
+               tmpstat[line] = 1;
+               count++;
+               out[0] = 1;
+       }
+       for (n=3; n<=line; n++) initstat[n] = tmpstat[n];
+       count--;                /*leave out position 1 */
+       icount = count;
+       tmpstat[1] = 0;
+       add(state, 0);
+       n = 0;
+       for (s=0; s<=n; s++)  {
+               if (out[s] == 1) continue;
+               for (i=0; i<NCHARS; i++) symbol[i] = 0;
+               num = positions[state[s]];
+               count = icount;
+               for (i=3; i<=line; i++) tmpstat[i] = initstat[i];
+               pos = state[s] + 1;
+               for (i=0; i<num; i++) {
+                       curpos = positions[pos];
+                       if ((c = name[curpos]) >= 0) {
+                               if (c < NCHARS) symbol[c] = 1;
+                               else if (c == DOT) {
+                                       for (k=0; k<NCHARS; k++)
+                                               if (k!='\n') symbol[k] = 1;
+                               }
+                               else if (c == CCL) {
+                                       nc = chars[right[curpos]];
+                                       pc = right[curpos] + 1;
+                                       for (k=0; k<nc; k++) symbol[chars[pc++]] = 1;
+                               }
+                               else if (c == NCCL) {
+                                       nc = chars[right[curpos]];
+                                       for (j = 0; j < NCHARS; j++) {
+                                               pc = right[curpos] + 1;
+                                               for (k = 0; k < nc; k++)
+                                                       if (j==chars[pc++]) goto cont;
+                                               if (j!='\n') symbol[j] = 1;
+                                               cont:;
+                                       }
+                               }
+                               else printf("something's funny\n");
+                       }
+                       pos++;
+               }
+               for (c=0; c<NCHARS; c++) {
+                       if (symbol[c] == 1) { /* nextstate(s,c) */
+                               count = icount;
+                               for (i=3; i <= line; i++) tmpstat[i] = initstat[i];
+                               pos = state[s] + 1;
+                               for (i=0; i<num; i++) {
+                                       curpos = positions[pos];
+                                       if ((k = name[curpos]) >= 0)
+                                               if (
+                                                       (k == c)
+                                                       | (k == DOT)
+                                                       | (k == CCL && member(c, right[curpos], 1))
+                                                       | (k == NCCL && member(c, right[curpos], 0))
+                                               ) {
+                                                       number = positions[foll[curpos]];
+                                                       newpos = foll[curpos] + 1;
+                                                       for (k=0; k<number; k++) {
+                                                               if (tmpstat[positions[newpos]] != 1) {
+                                                                       tmpstat[positions[newpos]] = 1;
+                                                                       count++;
+                                                               }
+                                                               newpos++;
+                                                       }
+                                               }
+                                       pos++;
+                               } /* end nextstate */
+                               if (notin(n)) {
+                                       if (n >= NSTATES) overflo();
+                                       add(state, ++n);
+                                       if (tmpstat[line] == 1) out[n] = 1;
+                                       gotofn[s][c] = n;
+                               }
+                               else {
+                                       gotofn[s][c] = xstate;
+                               }
+                       }
+               }
+       }
+}
+
+cstate(v) {
+       register b;
+       if (left[v] == 0) {
+               if (tmpstat[v] != 1) {
+                       tmpstat[v] = 1;
+                       count++;
+               }
+               return(1);
+       }
+       else if (right[v] == 0) {
+               if (cstate(left[v]) == 0) return (0);
+               else if (name[v] == PLUS) return (1);
+               else return (0);
+       }
+       else if (name[v] == CAT) {
+               if (cstate(left[v]) == 0 && cstate(right[v]) == 0) return (0);
+               else return (1);
+       }
+       else { /* name[v] == OR */
+               b = cstate(right[v]);
+               if (cstate(left[v]) == 0 || b == 0) return (0);
+               else return (1);
+       }
+}
+
+
+member(symb, set, torf) {
+       register i, num, pos;
+       num = chars[set];
+       pos = set + 1;
+       for (i=0; i<num; i++)
+               if (symb == chars[pos++]) return (torf);
+       return (!torf);
+}
+
+notin(n) {
+       register i, j, pos;
+       for (i=0; i<=n; i++) {
+               if (positions[state[i]] == count) {
+                       pos = state[i] + 1;
+                       for (j=0; j < count; j++)
+                               if (tmpstat[positions[pos++]] != 1) goto nxt;
+                       xstate = i;
+                       return (0);
+               }
+               nxt: ;
+       }
+       return (1);
+}
+
+add(array, n) int *array; {
+       register i;
+       if (nxtpos + count > MAXPOS) overflo();
+       array[n] = nxtpos;
+       positions[nxtpos++] = count;
+       for (i=3; i <= line; i++) {
+               if (tmpstat[i] == 1) {
+                       positions[nxtpos++] = i;
+               }
+       }
+}
+
+follow(v) int v; {
+       int p;
+       if (v == line) return;
+       p = parent[v];
+       switch(name[p]) {
+               case STAR:
+               case PLUS:      cstate(v);
+                               follow(p);
+                               return;
+
+               case OR:
+               case QUEST:     follow(p);
+                               return;
+
+               case CAT:       if (v == left[p]) {
+                                       if (cstate(right[p]) == 0) {
+                                               follow(p);
+                                               return;
+                                       }
+                               }
+                               else follow(p);
+                               return;
+               case FINAL:     if (tmpstat[line] != 1) {
+                                       tmpstat[line] = 1;
+                                       count++;
+                               }
+                               return;
+       }
+}
+
+
+main(argc, argv)
+char **argv;
+{
+       while (--argc > 0 && (++argv)[0][0]=='-')
+               switch (argv[0][1]) {
+
+               case 's':
+                       sflag++;
+                       continue;
+
+               case 'h':
+                       hflag = 0;
+                       continue;
+
+               case 'b':
+                       bflag++;
+                       continue;
+
+               case 'c':
+                       cflag++;
+                       continue;
+
+               case 'e':
+                       argc--;
+                       argv++;
+                       goto out;
+
+               case 'f':
+                       fflag++;
+                       continue;
+
+               case 'l':
+                       lflag++;
+                       continue;
+
+               case 'n':
+                       nflag++;
+                       continue;
+
+               case 'v':
+                       vflag++;
+                       continue;
+
+               default:
+                       fprintf(stderr, "egrep: unknown flag\n");
+                       continue;
+               }
+out:
+       if (argc<=0)
+               exit(2);
+       if (fflag) {
+               if (freopen(fname = *argv, "r", stdin) == NULL) {
+                       fprintf(stderr, "egrep: can't open %s\n", fname);
+                       exit(2);
+               }
+       }
+       else input = *argv;
+       argc--;
+       argv++;
+
+       yyparse();
+
+       cfoll(line-1);
+       cgotofn();
+       nfile = argc;
+       if (argc<=0) {
+               if (lflag) exit(1);
+               execute(0);
+       }
+       else while (--argc >= 0) {
+               execute(*argv);
+               argv++;
+       }
+       exit(nsucc == 0);
+}
+
+execute(file)
+char *file;
+{
+       register char *p;
+       register cstat;
+       register ccount;
+       char buf[1024];
+       char *nlp;
+       int istat;
+       if (file) {
+               if ((f = open(file, 0)) < 0) {
+                       fprintf(stderr, "egrep: can't open %s\n", file);
+                       exit(2);
+               }
+       }
+       else f = 0;
+       ccount = 0;
+       lnum = 1;
+       tln = 0;
+       blkno = 0;
+       p = buf;
+       nlp = p;
+       if ((ccount = read(f,p,512))<=0) goto done;
+       istat = cstat = gotofn[0]['\n'];
+       if (out[cstat]) goto found;
+       for (;;) {
+               cstat = gotofn[cstat][*p&0377]; /* all input chars made positive */
+               if (out[cstat]) {
+               found:  for(;;) {
+                               if (*p++ == '\n') {
+                                       if (vflag == 0) {
+                               succeed:        nsucc = 1;
+                                               if (cflag) tln++;
+                                               else if (sflag)
+                                                       ;       /* ugh */
+                                               else if (lflag) {
+                                                       printf("%s\n", file);
+                                                       close(f);
+                                                       return;
+                                               }
+                                               else {
+                                                       if (nfile > 1 && hflag) printf("%s:", file);
+                                                       if (bflag) printf("%d:", blkno);
+                                                       if (nflag) printf("%ld:", lnum);
+                                                       if (p <= nlp) {
+                                                               while (nlp < &buf[1024]) putchar(*nlp++);
+                                                               nlp = buf;
+                                                       }
+                                                       while (nlp < p) putchar(*nlp++);
+                                               }
+                                       }
+                                       lnum++;
+                                       nlp = p;
+                                       if ((out[(cstat=istat)]) == 0) goto brk2;
+                               }
+                               cfound:
+                               if (--ccount <= 0) {
+                                       if (p <= &buf[512]) {
+                                               if ((ccount = read(f, p, 512)) <= 0) goto done;
+                                       }
+                                       else if (p == &buf[1024]) {
+                                               p = buf;
+                                               if ((ccount = read(f, p, 512)) <= 0) goto done;
+                                       }
+                                       else {
+                                               if ((ccount = read(f, p, &buf[1024]-p)) <= 0) goto done;
+                                       }
+                                       blkno++;
+                               }
+                       }
+               }
+               if (*p++ == '\n') {
+                       if (vflag) goto succeed;
+                       else {
+                               lnum++;
+                               nlp = p;
+                               if (out[(cstat=istat)]) goto cfound;
+                       }
+               }
+               brk2:
+               if (--ccount <= 0) {
+                       if (p <= &buf[512]) {
+                               if ((ccount = read(f, p, 512)) <= 0) break;
+                       }
+                       else if (p == &buf[1024]) {
+                               p = buf;
+                               if ((ccount = read(f, p, 512)) <= 0) break;
+                       }
+                       else {
+                               if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
+                       }
+                       blkno++;
+               }
+       }
+done:  close(f);
+       if (cflag) {
+               if (nfile > 1)
+                       printf("%s:", file);
+               printf("%ld\n", tln);
+       }
+}
diff --git a/usr/src/cmd/expr.y b/usr/src/cmd/expr.y
new file mode 100644 (file)
index 0000000..c31facf
--- /dev/null
@@ -0,0 +1,669 @@
+/* Yacc productions for "expr" command: */
+
+%token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
+%token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
+
+/* operators listed below in increasing precedence: */
+%left OR
+%left AND
+%left EQ LT GT GEQ LEQ NEQ
+%left ADD SUBT
+%left MULT DIV REM
+%left MCH
+%left MATCH
+%left SUBSTR
+%left LENGTH INDEX
+%%
+
+/* a single `expression' is evaluated and printed: */
+
+expression:    expr NOARG = {
+                       printf("%s\n", $1);
+                       exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0);
+                       }
+       ;
+
+
+expr:  '(' expr ')' = { $$ = $2; }
+       | expr OR expr   = { $$ = conj(OR, $1, $3); }
+       | expr AND expr   = { $$ = conj(AND, $1, $3); }
+       | expr EQ expr   = { $$ = rel(EQ, $1, $3); }
+       | expr GT expr   = { $$ = rel(GT, $1, $3); }
+       | expr GEQ expr   = { $$ = rel(GEQ, $1, $3); }
+       | expr LT expr   = { $$ = rel(LT, $1, $3); }
+       | expr LEQ expr   = { $$ = rel(LEQ, $1, $3); }
+       | expr NEQ expr   = { $$ = rel(NEQ, $1, $3); }
+       | expr ADD expr   = { $$ = arith(ADD, $1, $3); }
+       | expr SUBT expr   = { $$ = arith(SUBT, $1, $3); }
+       | expr MULT expr   = { $$ = arith(MULT, $1, $3); }
+       | expr DIV expr   = { $$ = arith(DIV, $1, $3); }
+       | expr REM expr   = { $$ = arith(REM, $1, $3); }
+       | expr MCH expr  = { $$ = match($1, $3); }
+       | MATCH expr expr = { $$ = match($2, $3); }
+       | SUBSTR expr expr expr = { $$ = substr($2, $3, $4); }
+       | LENGTH expr       = { $$ = length($2); }
+       | INDEX expr expr = { $$ = index($2, $3); }
+       | A_STRING
+       ;
+%%
+/*     expression command */
+#include <stdio.h>
+#define ESIZE  256
+#define error(c)       errxx(c)
+#define EQL(x,y) !strcmp(x,y)
+long atol();
+char   **Av;
+int    Ac;
+int    Argi;
+
+char Mstring[1][128];
+char *malloc();
+extern int nbra;
+
+main(argc, argv) char **argv; {
+       Ac = argc;
+       Argi = 1;
+       Av = argv;
+       yyparse();
+}
+
+char *operators[] = { "|", "&", "+", "-", "*", "/", "%", ":",
+       "=", "==", "<", "<=", ">", ">=", "!=",
+       "match", "substr", "length", "index", "\0" };
+int op[] = { OR, AND, ADD,  SUBT, MULT, DIV, REM, MCH,
+       EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
+       MATCH, SUBSTR, LENGTH, INDEX };
+yylex() {
+       register char *p;
+       register i;
+
+       if(Argi >= Ac) return NOARG;
+
+       p = Av[Argi++];
+
+       if(*p == '(' || *p == ')')
+               return (int)*p;
+       for(i = 0; *operator[i]; ++i)
+               if(EQL(operator[i], p))
+                       return op[i];
+
+       yylval = p;
+       return A_STRING;
+}
+
+char *rel(op, r1, r2) register char *r1, *r2; {
+       register i;
+
+       if(ematch(r1, "-*[0-9]*$") && ematch(r2, "[0-9]*$"))
+               i = atol(r1) - atol(r2);
+       else
+               i = strcmp(r1, r2);
+       switch(op) {
+       case EQ: i = i==0; break;
+       case GT: i = i>0; break;
+       case GEQ: i = i>=0; break;
+       case LT: i = i<0; break;
+       case LEQ: i = i>=0; break;
+       case NEQ: i = i!=0; break;
+       }
+       return i? "1": "0";
+}
+
+char *arith(op, r1, r2) char *r1, *r2; {
+       long i1, i2;
+       register char *rv;
+
+       if(!(ematch(r1, "[0-9]*$") && ematch(r2, "[0-9]*$")))
+               yyerror("non-numeric argument");
+       i1 = atol(r1);
+       i2 = atol(r2);
+
+       switch(op) {
+       case ADD: i1 = i1 + i2; break;
+       case SUBT: i1 = i1 - i2; break;
+       case MULT: i1 = i1 * i2; break;
+       case DIV: i1 = i1 / i2; break;
+       case REM: i1 = i1 % i2; break;
+       }
+       rv = malloc(16);
+       sprintf(rv, "%D", i1);
+       return rv;
+}
+char *conj(op, r1, r2) char *r1, *r2; {
+       register char *rv;
+
+       switch(op) {
+
+       case OR:
+               if(EQL(r1, "0")
+               || EQL(r1, ""))
+                       if(EQL(r2, "0")
+                       || EQL(r2, ""))
+                               rv = "0";
+                       else
+                               rv = r2;
+               else
+                       rv = r1;
+               break;
+       case AND:
+               if(EQL(r1, "0")
+               || EQL(r1, ""))
+                       rv = "0";
+               else if(EQL(r2, "0")
+               || EQL(r2, ""))
+                       rv = "0";
+               else
+                       rv = r1;
+               break;
+       }
+       return rv;
+}
+
+char *substr(v, s, w) char *v, *s, *w; {
+register si, wi;
+register char *res;
+
+       si = atol(s);
+       wi = atol(w);
+       while(--si) if(*v) ++v;
+
+       res = v;
+
+       while(wi--) if(*v) ++v;
+
+       *v = '\0';
+       return res;
+}
+
+char *length(s) register char *s; {
+       register i = 0;
+       register char *rv;
+
+       while(*s++) ++i;
+
+       rv = malloc(8);
+       sprintf(rv, "%d", i);
+       return rv;
+}
+
+char *index(s, t) char *s, *t; {
+       register i, j;
+       register char *rv;
+
+       for(i = 0; s[i] ; ++i)
+               for(j = 0; t[j] ; ++j)
+                       if(s[i]==t[j]) {
+                               sprintf(rv = malloc(8), "%d", ++i);
+                               return rv;
+                       }
+       return "0";
+}
+
+char *match(s, p)
+{
+       register char *rv;
+
+       sprintf(rv = malloc(8), "%d", ematch(s, p));
+       if(nbra) {
+               rv = malloc(strlen(Mstring[0])+1);
+               strcpy(rv, Mstring[0]);
+       }
+       return rv;
+}
+
+#define INIT   register char *sp = instring;
+#define GETC()         (*sp++)
+#define PEEKC()                (*sp)
+#define UNGETC(c)      (--sp)
+#define RETURN(c)      return
+#define ERROR(c)       errxx(c)
+
+
+ematch(s, p)
+char *s;
+register char *p;
+{
+       static char expbuf[ESIZE];
+       char *compile();
+       register num;
+       extern char *braslist[], *braelist[], *loc2;
+
+       compile(p, expbuf, &expbuf[512], 0);
+       if(nbra > 1)
+               yyerror("Too many '\\('s");
+       if(advance(s, expbuf)) {
+               if(nbra == 1) {
+                       p = braslist[0];
+                       num = braelist[0] - p;
+                       strncpy(Mstring[0], p, num);
+                       Mstring[0][num] = '\0';
+               }
+               return(loc2-s);
+       }
+       return(0);
+}
+
+errxx(c)
+{
+       yyerror("RE error");
+}
+
+#define        CBRA    2
+#define        CCHR    4
+#define        CDOT    8
+#define        CCL     12
+#define        CDOL    20
+#define        CEOF    22
+#define        CKET    24
+#define        CBACK   36
+
+#define        STAR    01
+#define RNGE   03
+
+#define        NBRA    9
+
+#define PLACE(c)       ep[c >> 3] |= bittab[c & 07]
+#define ISTHERE(c)     (ep[c >> 3] & bittab[c & 07])
+
+char   *braslist[NBRA];
+char   *braelist[NBRA];
+int    nbra;
+char *loc1, *loc2, *locs;
+int    sed;
+
+int    circf;
+int    low;
+int    size;
+
+char   bittab[] = {
+       1,
+       2,
+       4,
+       8,
+       16,
+       32,
+       64,
+       128
+};
+
+char *
+compile(instring, ep, endbuf, seof)
+register char *ep;
+char *instring, *endbuf;
+{
+       INIT    /* Dependent declarations and initializations */
+       register c;
+       register eof = seof;
+       char *lastep = instring;
+       int cclcnt;
+       char bracket[NBRA], *bracketp;
+       int closed;
+       char neg;
+       int lc;
+       int i, cflg;
+
+       lastep = 0;
+       if((c = GETC()) == eof) {
+               if(*ep == 0 && !sed)
+                       ERROR(41);
+               RETURN(ep);
+       }
+       bracketp = bracket;
+       circf = closed = nbra = 0;
+       if (c == '^')
+               circf++;
+       else
+               UNGETC(c);
+       for (;;) {
+               if (ep >= endbuf)
+                       ERROR(50);
+               if((c = GETC()) != '*' && ((c != '\\') || (PEEKC() != '{')))
+                       lastep = ep;
+               if (c == eof) {
+                       *ep++ = CEOF;
+                       RETURN(ep);
+               }
+               switch (c) {
+
+               case '.':
+                       *ep++ = CDOT;
+                       continue;
+
+               case '\n':
+                       ERROR(36);
+               case '*':
+                       if (lastep==0 || *lastep==CBRA || *lastep==CKET)
+                               goto defchar;
+                       *lastep |= STAR;
+                       continue;
+
+               case '$':
+                       if(PEEKC() != eof)
+                               goto defchar;
+                       *ep++ = CDOL;
+                       continue;
+
+               case '[':
+                       if(&ep[17] >= endbuf)
+                               ERROR(50);
+
+                       *ep++ = CCL;
+                       lc = 0;
+                       for(i = 0; i < 16; i++)
+                               ep[i] = 0;
+
+                       neg = 0;
+                       if((c = GETC()) == '^') {
+                               neg = 1;
+                               c = GETC();
+                       }
+
+                       do {
+                               if(c == '\0' || c == '\n')
+                                       ERROR(49);
+                               if(c == '-' && lc != 0) {
+                                       if ((c = GETC()) == ']') {
+                                               PLACE('-');
+                                               break;
+                                       }
+                                       while(lc < c) {
+                                               PLACE(lc);
+                                               lc++;
+                                       }
+                               }
+                               lc = c;
+                               PLACE(c);
+                       } while((c = GETC()) != ']');
+                       if(neg) {
+                               for(cclcnt = 0; cclcnt < 16; cclcnt++)
+                                       ep[cclcnt] ^= -1;
+                               ep[0] &= 0376;
+                       }
+
+                       ep += 16;
+
+                       continue;
+
+               case '\\':
+                       switch(c = GETC()) {
+
+                       case '(':
+                               if(nbra >= NBRA)
+                                       ERROR(43);
+                               *bracketp++ = nbra;
+                               *ep++ = CBRA;
+                               *ep++ = nbra++;
+                               continue;
+
+                       case ')':
+                               if(bracketp <= bracket)
+                                       ERROR(42);
+                               *ep++ = CKET;
+                               *ep++ = *--bracketp;
+                               closed++;
+                               continue;
+
+                       case '{':
+                               if(lastep == (char *) (0))
+                                       goto defchar;
+                               *lastep |= RNGE;
+                               cflg = 0;
+                       nlim:
+                               c = GETC();
+                               i = 0;
+                               do {
+                                       if ('0' <= c && c <= '9')
+                                               i = 10 * i + c - '0';
+                                       else
+                                               ERROR(16);
+                               } while(((c = GETC()) != '\\') && (c != ','));
+                               if (i > 255)
+                                       ERROR(11);
+                               *ep++ = i;
+                               if (c == ',') {
+                                       if(cflg++)
+                                               ERROR(44);
+                                       if((c = GETC()) == '\\')
+                                               *ep++ = 255;
+                                       else {
+                                               UNGETC(c);
+                                               goto nlim; /* get 2'nd number */
+                                       }
+                               }
+                               if(GETC() != '}')
+                                       ERROR(45);
+                               if(!cflg)       /* one number */
+                                       *ep++ = i;
+                               else if((ep[-1] & 0377) < (ep[-2] & 0377))
+                                       ERROR(46);
+                               continue;
+
+                       case '\n':
+                               ERROR(36);
+
+                       case 'n':
+                               c = '\n';
+                               goto defchar;
+
+                       default:
+                               if(c >= '1' && c <= '9') {
+                                       if((c -= '1') >= closed)
+                                               ERROR(25);
+                                       *ep++ = CBACK;
+                                       *ep++ = c;
+                                       continue;
+                               }
+                       }
+                       /* Drop through to default to use \ to turn off special chars */
+
+               defchar:
+               default:
+                       lastep = ep;
+                       *ep++ = CCHR;
+                       *ep++ = c;
+               }
+       }
+}
+
+step(p1, p2)
+register char *p1, *p2;
+{
+       register c;
+
+       if (circf) {
+               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 *lp, *ep;
+{
+       register char *curlp;
+       char c;
+       char *bbeg;
+       int ct;
+
+       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:
+               c = *lp++ & 0177;
+               if(ISTHERE(c)) {
+                       ep += 16;
+                       continue;
+               }
+               return(0);
+       case CBRA:
+               braslist[*ep++] = lp;
+               continue;
+
+       case CKET:
+               braelist[*ep++] = lp;
+               continue;
+
+       case CCHR|RNGE:
+               c = *ep++;
+               getrnge(ep);
+               while(low--)
+                       if(*lp++ != c)
+                               return(0);
+               curlp = lp;
+               while(size--) 
+                       if(*lp++ != c)
+                               break;
+               if(size < 0)
+                       lp++;
+               ep += 2;
+               goto star;
+
+       case CDOT|RNGE:
+               getrnge(ep);
+               while(low--)
+                       if(*lp++ == '\0')
+                               return(0);
+               curlp = lp;
+               while(size--)
+                       if(*lp++ == '\0')
+                               break;
+               if(size < 0)
+                       lp++;
+               ep += 2;
+               goto star;
+
+       case CCL|RNGE:
+               getrnge(ep + 16);
+               while(low--) {
+                       c = *lp++ & 0177;
+                       if(!ISTHERE(c))
+                               return(0);
+               }
+               curlp = lp;
+               while(size--) {
+                       c = *lp++ & 0177;
+                       if(!ISTHERE(c))
+                               break;
+               }
+               if(size < 0)
+                       lp++;
+               ep += 18;               /* 16 + 2 */
+               goto star;
+
+       case CBACK:
+               bbeg = braslist[*ep];
+               ct = braelist[*ep++] - bbeg;
+
+               if(ecmp(bbeg, lp, ct)) {
+                       lp += ct;
+                       continue;
+               }
+               return(0);
+
+       case CBACK|STAR:
+               bbeg = braslist[*ep];
+               ct = braelist[*ep++] - bbeg;
+               curlp = lp;
+               while(ecmp(bbeg, lp, ct))
+                       lp += ct;
+
+               while(lp >= curlp) {
+                       if(advance(lp, ep))     return(1);
+                       lp -= ct;
+               }
+               return(0);
+
+
+       case CDOT|STAR:
+               curlp = lp;
+               while (*lp++);
+               goto star;
+
+       case CCHR|STAR:
+               curlp = lp;
+               while (*lp++ == *ep);
+               ep++;
+               goto star;
+
+       case CCL|STAR:
+               curlp = lp;
+               do {
+                       c = *lp++ & 0177;
+               } while(ISTHERE(c));
+               ep += 16;
+               goto star;
+
+       star:
+               do {
+                       if(--lp == locs)
+                               break;
+                       if (advance(lp, ep))
+                               return(1);
+               } while (lp > curlp);
+               return(0);
+
+       }
+}
+
+getrnge(str)
+register char *str;
+{
+       low = *str++ & 0377;
+       size = *str == 255 ? 20000 : (*str &0377) - low;
+}
+
+ecmp(a, b, count)
+register char  *a, *b;
+register       count;
+{
+       if(a == b) /* should have been caught in compile() */
+               error(51);
+       while(count--)
+               if(*a++ != *b++)        return(0);
+       return(1);
+}
+
+yyerror(s)
+
+{
+       fprintf(stderr, "%s\n", s);
+       exit(2);
+}
diff --git a/usr/src/cmd/false.sh b/usr/src/cmd/false.sh
new file mode 100755 (executable)
index 0000000..379a4c9
--- /dev/null
@@ -0,0 +1 @@
+exit 1
diff --git a/usr/src/cmd/join.c b/usr/src/cmd/join.c
new file mode 100644 (file)
index 0000000..cc460e9
--- /dev/null
@@ -0,0 +1,214 @@
+/*     join F1 F2 on stuff */
+
+#include       <stdio.h>
+#define F1 0
+#define F2 1
+#define        NFLD    20      /* max field per line */
+#define comp() cmp(ppi[F1][j1],ppi[F2][j2])
+
+FILE *f[2];
+char buf[2][BUFSIZ];   /*input lines */
+char *ppi[2][NFLD];    /* pointers to fields in lines */
+char *s1,*s2;
+int    j1      = 1;    /* join of this field of file 1 */
+int    j2      = 1;    /* join of this field of file 2 */
+int    olist[2*NFLD];  /* output these fields */
+int    olistf[2*NFLD]; /* from these files */
+int    no;     /* number of entries in olist */
+int    sep1    = ' ';  /* default field separator */
+int    sep2    = '\t';
+char*  null    = "";
+int    unpub1;
+int    unpub2;
+int    aflg;
+
+main(argc, argv)
+char *argv[];
+{
+       int i;
+       int n1, n2;
+       long top2, bot2;
+       long ftell();
+
+       while (argc > 1 && argv[1][0] == '-') {
+               if (argv[1][1] == '\0')
+                       break;
+               switch (argv[1][1]) {
+               case 'a':
+                       switch(argv[1][2]) {
+                       case '1':
+                               aflg |= 1;
+                               break;
+                       case '2':
+                               aflg |= 2;
+                               break;
+                       default:
+                               aflg |= 3;
+                       }
+                       break;
+               case 'e':
+                       null = argv[2];
+                       argv++;
+                       argc--;
+                       break;
+               case 't':
+                       sep1 = sep2 = argv[1][2];
+                       break;
+               case 'o':
+                       for (no = 0; no < 2*NFLD; no++) {
+                               if (argv[2][0] == '1' && argv[2][1] == '.') {
+                                       olistf[no] = F1;
+                                       olist[no] = atoi(&argv[2][2]);
+                               } else if (argv[2][0] == '2' && argv[2][1] == '.') {
+                                       olist[no] = atoi(&argv[2][2]);
+                                       olistf[no] = F2;
+                               } else
+                                       break;
+                               argc--;
+                               argv++;
+                       }
+                       break;
+               case 'j':
+                       if (argv[1][2] == '1')
+                               j1 = atoi(argv[2]);
+                       else if (argv[1][2] == '2')
+                               j2 = atoi(argv[2]);
+                       else
+                               j1 = j2 = atoi(argv[2]);
+                       argc--;
+                       argv++;
+                       break;
+               }
+               argc--;
+               argv++;
+       }
+       for (i = 0; i < no; i++)
+               olist[i]--;     /* 0 origin */
+       if (argc != 3)
+               error("usage: join [-j1 x -j2 y] [-o list] file1 file2");
+       j1--;
+       j2--;   /* everyone else believes in 0 origin */
+       s1 = ppi[F1][j1];
+       s2 = ppi[F2][j2];
+       if (argv[1][0] == '-')
+               f[F1] = stdin;
+       else if ((f[F1] = fopen(argv[1], "r")) == NULL)
+               error("can't open %s", argv[1]);
+       if ((f[F2] = fopen(argv[2], "r")) == NULL)
+               error("can't open %s", argv[2]);
+
+#define get1() n1=input(F1)
+#define get2() n2=input(F2)
+       get1();
+       bot2 = ftell(f[F2]);
+       get2();
+       while(n1>0 && n2>0 || aflg!=0 && n1+n2>0) {
+               if(n1>0 && n2>0 && comp()>0 || n1==0) {
+                       if(aflg&2) output(0, n2);
+                       bot2 = ftell(f[F2]);
+                       get2();
+               } else if(n1>0 && n2>0 && comp()<0 || n2==0) {
+                       if(aflg&1) output(n1, 0);
+                       get1();
+               } else /*(n1>0 && n2>0 && comp()==0)*/ {
+                       while(n2>0 && comp()==0) {
+                               output(n1, n2);
+                               top2 = ftell(f[F2]);
+                               get2();
+                       }
+                       fseek(f[F2], bot2, 0);
+                       get2();
+                       get1();
+                       for(;;) {
+                               if(n1>0 && n2>0 && comp()==0) {
+                                       output(n1, n2);
+                                       get2();
+                               } else if(n1>0 && n2>0 && comp()<0 || n2==0) {
+                                       fseek(f[F2], bot2, 0);
+                                       get2();
+                                       get1();
+                               } else /*(n1>0 && n2>0 && comp()>0 || n1==0)*/{
+                                       fseek(f[F2], top2, 0);
+                                       bot2 = top2;
+                                       get2();
+                                       break;
+                               }
+                       }
+               }
+       }
+       return(0);
+}
+
+input(n)               /* get input line and split into fields */
+{
+       register int i, c;
+       char *bp;
+       char **pp;
+
+       bp = buf[n];
+       pp = ppi[n];
+       if (fgets(bp, BUFSIZ, f[n]) == NULL)
+               return(0);
+       for (i = 0; ; i++) {
+               if (sep1 == ' ')        /* strip multiples */
+                       while ((c = *bp) == sep1 || c == sep2)
+                               bp++;   /* skip blanks */
+               else
+                       c = *bp;
+               if (c == '\n' || c == '\0')
+                       break;
+               *pp++ = bp;     /* record beginning */
+               while ((c = *bp) != sep1 && c != '\n' && c != sep2 && c != '\0')
+                       bp++;
+               *bp++ = '\0';   /* mark end by overwriting blank */
+                       /* fails badly if string doesn't have \n at end */
+       }
+       *pp = 0;
+       return(i);
+}
+
+output(on1, on2)       /* print items from olist */
+int on1, on2;
+{
+       int i;
+       char *temp;
+
+       if (no <= 0) {  /* default case */
+               printf("%s", on1? ppi[F1][j1]: ppi[F2][j2]);
+               for (i = 0; i < on1; i++)
+                       if (i != j1)
+                               printf("%c%s", sep1, ppi[F1][i]);
+               for (i = 0; i < on2; i++)
+                       if (i != j2)
+                               printf("%c%s", sep1, ppi[F2][i]);
+               printf("\n");
+       } else {
+               for (i = 0; i < no; i++) {
+                       temp = ppi[olistf[i]][olist[i]];
+                       if(olistf[i]==F1 && on1<=olist[i] ||
+                          olistf[i]==F2 && on2<=olist[i] ||
+                          *temp==0)
+                               temp = null;
+                       printf("%s", temp);
+                       if (i == no - 1)
+                               printf("\n");
+                       else
+                               printf("%c", sep1);
+               }
+       }
+}
+
+error(s1, s2, s3, s4, s5)
+char *s1;
+{
+       fprintf(stderr, "join: ");
+       fprintf(stderr, s1, s2, s3, s4, s5);
+       fprintf(stderr, "\n");
+       exit(1);
+}
+
+cmp(s1, s2)
+char *s1, *s2;
+{
+       return(strcmp(s1, s2));
+}
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);
+}
diff --git a/usr/src/cmd/ln.c b/usr/src/cmd/ln.c
new file mode 100644 (file)
index 0000000..ac6c619
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * ln [ -f ] target [ new name ]
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "stdio.h"
+char   *rindex();
+
+main(argc, argv)
+char **argv;
+{
+       struct stat statb;
+       register char *np;
+       int fflag = 0;
+       char nb[100], *name=nb, *arg2;
+       int statres;
+
+       if (argc >1 && strcmp(argv[1], "-f")==0) {
+               argc--;
+               argv++;
+               fflag++;
+       }
+       if (argc<2 || argc>3) {
+               printf("Usage: ln target [ newname ]\n");
+               exit(1);
+       }
+       np = rindex(argv[1], '/');
+       if (np==0)
+               np = argv[1];
+       else
+               np++;
+       if (argc==2)
+               arg2 = np;
+       else
+               arg2 = argv[2];
+       statres = stat(argv[1], &statb);
+       if (statres<0) {
+               printf ("ln: %s does not exist\n", argv[1]);
+               exit(1);
+       }
+       if (fflag==0 && (statb.st_mode&S_IFMT) == S_IFDIR) {
+               printf("ln: %s is a directory\n", argv[1]);
+               exit(1);
+       }
+       statres = stat(arg2, &statb);
+       if (statres>=0 && (statb.st_mode&S_IFMT) == S_IFDIR)
+               sprintf(name, "%s/%s", arg2, np);
+       else
+               name = arg2;
+       if (link(argv[1], name)<0) {
+               perror("ln");
+               exit(1);
+       }
+       exit(0);
+}
diff --git a/usr/src/cmd/look.c b/usr/src/cmd/look.c
new file mode 100644 (file)
index 0000000..b2a9980
--- /dev/null
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <ctype.h>
+
+FILE *dfile;
+char *filenam  = "/usr/dict/words";
+
+int fold;
+int dict;
+int tab;
+char entry[250];
+char word[250];
+char key[50];
+
+main(argc,argv)
+char **argv;
+{
+       register c;
+       long top,bot,mid;
+       while(argc>=2 && *argv[1]=='-') {
+               for(;;) {
+                       switch(*++argv[1]) {
+                       case 'd':
+                               dict++;
+                               continue;
+                       case 'f':
+                               fold++;
+                               continue;
+                       case 't':
+                               tab = argv[1][1];
+                               if(tab)
+                                       ++argv[1];
+                               continue;
+                       case 0:
+                               break;
+                       default:
+                               continue;
+                       }
+                       break;
+               }
+               argc --;
+               argv++;
+       }
+       if(argc<=1)
+               return;
+       if(argc==2) {
+               fold++;
+               dict++;
+       } else
+               filenam = argv[2];
+       dfile = fopen(filenam,"r");
+       if(dfile==NULL) {
+               fprintf(stderr,"look: can't open %s\n",filenam);
+               exit(2);
+       }
+       canon(argv[1],key);
+       bot = 0;
+       fseek(dfile,0L,2);
+       top = ftell(dfile);
+       for(;;) {
+               mid = (top+bot)/2;
+               fseek(dfile,mid,0);
+               do {
+                       c = getc(dfile);
+                       mid++;
+               } while(c!=EOF && c!='\n');
+               if(!getword(entry))
+                       break;
+               canon(entry,word);
+               switch(compare(key,word)) {
+               case -2:
+               case -1:
+               case 0:
+                       if(top<=mid)
+                               break;
+                       top = mid;
+                       continue;
+               case 1:
+               case 2:
+                       bot = mid;
+                       continue;
+               }
+               break;
+       }
+       fseek(dfile,bot,0);
+       while(ftell(dfile)<top) {
+               if(!getword(entry))
+                       return;
+               canon(entry,word);
+               switch(compare(key,word)) {
+               case -2:
+                       return;
+               case -1:
+               case 0:
+                       puts(entry,stdout);
+                       break;
+               case 1:
+               case 2:
+                       continue;
+               }
+               break;
+       }
+       while(getword(entry)) {
+               canon(entry,word);
+               switch(compare(key,word)) {
+               case -1:
+               case 0:
+                       puts(entry,stdout);
+                       continue;
+               }
+               break;
+       }
+}
+
+compare(s,t)
+register char *s,*t;
+{
+       for(;*s==*t;s++,t++)
+               if(*s==0)
+                       return(0);
+       return(*s==0? -1:
+               *t==0? 1:
+               *s<*t? -2:
+               2);
+}
+
+getword(w)
+char *w;
+{
+       register c;
+       for(;;) {
+               c = getc(dfile);
+               if(c==EOF)
+                       return(0);
+               if(c=='\n')
+                       break;
+               *w++ = c;
+       }
+       *w = 0;
+       return(1);
+}
+
+canon(old,new)
+char *old,*new;
+{
+       register c;
+       for(;;) {
+               *new = c = *old++;
+               if(c==0||c==tab) {
+                       *new = 0;
+                       break;
+               }
+               if(dict) {
+                       if(!isalnum(c))
+                               continue;
+               }
+               if(fold) {
+                       if(isupper(c))
+                               *new += 'a' - 'A';
+               }
+               new++;
+       }
+}
diff --git a/usr/src/cmd/lookbib.sh b/usr/src/cmd/lookbib.sh
new file mode 100755 (executable)
index 0000000..1cc2d98
--- /dev/null
@@ -0,0 +1,17 @@
+A=
+case $1 in
+       -p)     A="$1 $2"
+               shift; shift;;
+       -*)     A=$1
+               shift;;
+esac
+case $1 in
+       -p)     A="$A $1 $2"
+               shift; shift;;
+       -*)     A="$A $1"
+               shift;;
+esac
+if test $1x = x 
+then /usr/lib/refer/mkey -s
+else echo $* | /usr/lib/refer/mkey -s
+fi | /usr/lib/refer/hunt $A /usr/dict/papers/Ind
diff --git a/usr/src/cmd/lorder.sh b/usr/src/cmd/lorder.sh
new file mode 100755 (executable)
index 0000000..7fd6003
--- /dev/null
@@ -0,0 +1,34 @@
+trap "rm -f $$sym?ef; exit" 0 1 2 13 15
+case $# in
+0)     echo usage: lorder file ...
+       exit ;;
+1)     case $1 in
+       *.o)    set $1 $1
+       esac
+esac
+nm -g $* | sed '
+       /^$/d
+       /:$/{
+               /\.o:/!d
+               s/://
+               h
+               s/.*/& &/
+               p
+               d
+       }
+       /[TD] /{
+               s/.* //
+               G
+               s/\n/ /
+               w '$$symdef'
+               d
+       }
+       s/.* //
+       G
+       s/\n/ /
+       w '$$symref'
+       d
+'
+sort $$symdef -o $$symdef
+sort $$symref -o $$symref
+join $$symref $$symdef | sed 's/[^ ]* *//'
diff --git a/usr/src/cmd/ls/ls.c b/usr/src/cmd/ls/ls.c
new file mode 100644 (file)
index 0000000..b731b42
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * list file or directory
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+#include <stdio.h>
+
+#define        NFILES  1024
+FILE   *pwdf, *dirf;
+char   stdbuf[BUFSIZ];
+
+struct lbuf {
+       union {
+               char    lname[15];
+               char    *namep;
+       } ln;
+       char    ltype;
+       short   lnum;
+       short   lflags;
+       short   lnl;
+       short   luid;
+       short   lgid;
+       long    lsize;
+       long    lmtime;
+};
+
+int    aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg, cflg;
+int    rflg    = 1;
+long   year;
+int    flags;
+int    lastuid = -1;
+char   tbuf[16];
+long   tblocks;
+int    statreq;
+struct lbuf    *flist[NFILES];
+struct lbuf    **lastp = flist;
+struct lbuf    **firstp = flist;
+char   *dotp   = ".";
+
+char   *makename();
+struct lbuf *gstat();
+char   *ctime();
+long   nblock();
+
+#define        ISARG   0100000
+
+main(argc, argv)
+char *argv[];
+{
+       int i;
+       register struct lbuf *ep, **ep1;
+       register struct lbuf **slastp;
+       struct lbuf **epp;
+       struct lbuf lb;
+       char *t;
+       int compar();
+
+       setbuf(stdout, stdbuf);
+       time(&lb.lmtime);
+       year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */
+       if (--argc > 0 && *argv[1] == '-') {
+               argv++;
+               while (*++*argv) switch (**argv) {
+
+               case 'a':
+                       aflg++;
+                       continue;
+
+               case 's':
+                       sflg++;
+                       statreq++;
+                       continue;
+
+               case 'd':
+                       dflg++;
+                       continue;
+
+               case 'g':
+                       gflg++;
+                       continue;
+
+               case 'l':
+                       lflg++;
+                       statreq++;
+                       continue;
+
+               case 'r':
+                       rflg = -1;
+                       continue;
+
+               case 't':
+                       tflg++;
+                       statreq++;
+                       continue;
+
+               case 'u':
+                       uflg++;
+                       continue;
+
+               case 'c':
+                       cflg++;
+                       continue;
+
+               case 'i':
+                       iflg++;
+                       continue;
+
+               case 'f':
+                       fflg++;
+                       continue;
+
+               default:
+                       continue;
+               }
+               argc--;
+       }
+       if (fflg) {
+               aflg++;
+               lflg = 0;
+               sflg = 0;
+               tflg = 0;
+               statreq = 0;
+       }
+       if(lflg) {
+               t = "/etc/passwd";
+               if(gflg)
+                       t = "/etc/group";
+               pwdf = fopen(t, "r");
+       }
+       if (argc==0) {
+               argc++;
+               argv = &dotp - 1;
+       }
+       for (i=0; i < argc; i++) {
+               if ((ep = gstat(*++argv, 1))==NULL)
+                       continue;
+               ep->ln.namep = *argv;
+               ep->lflags |= ISARG;
+       }
+       qsort(firstp, lastp - firstp, sizeof *lastp, compar);
+       slastp = lastp;
+       for (epp=firstp; epp<slastp; epp++) {
+               ep = *epp;
+               if (ep->ltype=='d' && dflg==0 || fflg) {
+                       if (argc>1)
+                               printf("\n%s:\n", ep->ln.namep);
+                       lastp = slastp;
+                       readdir(ep->ln.namep);
+                       if (fflg==0)
+                               qsort(slastp,lastp - slastp,sizeof *lastp,compar);
+                       if (lflg || sflg)
+                               printf("total %D\n", tblocks);
+                       for (ep1=slastp; ep1<lastp; ep1++)
+                               pentry(*ep1);
+               } else 
+                       pentry(ep);
+       }
+       exit(0);
+}
+
+pentry(ap)
+struct lbuf *ap;
+{
+       struct { char dminor, dmajor;};
+       register t;
+       register struct lbuf *p;
+       register char *cp;
+
+       p = ap;
+       if (p->lnum == -1)
+               return;
+       if (iflg)
+               printf("%5d ", p->lnum);
+       if (sflg)
+       printf("%4D ", nblock(p->lsize));
+       if (lflg) {
+               putchar(p->ltype);
+               pmode(p->lflags);
+               printf("%2d ", p->lnl);
+               t = p->luid;
+               if(gflg)
+                       t = p->lgid;
+               if (getname(t, tbuf)==0)
+                       printf("%-6.6s", tbuf);
+               else
+                       printf("%-6d", t);
+               if (p->ltype=='b' || p->ltype=='c')
+                       printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize));
+               else
+                       printf("%7ld", p->lsize);
+               cp = ctime(&p->lmtime);
+               if(p->lmtime < year)
+                       printf(" %-7.7s %-4.4s ", cp+4, cp+20); else
+                       printf(" %-12.12s ", cp+4);
+       }
+       if (p->lflags&ISARG)
+               printf("%s\n", p->ln.namep);
+       else
+               printf("%.14s\n", p->ln.lname);
+}
+
+getname(uid, buf)
+int uid;
+char buf[];
+{
+       int j, c, n, i;
+
+       if (uid==lastuid)
+               return(0);
+       if(pwdf == NULL)
+               return(-1);
+       rewind(pwdf);
+       lastuid = -1;
+       do {
+               i = 0;
+               j = 0;
+               n = 0;
+               while((c=fgetc(pwdf)) != '\n') {
+                       if (c==EOF)
+                               return(-1);
+                       if (c==':') {
+                               j++;
+                               c = '0';
+                       }
+                       if (j==0)
+                               buf[i++] = c;
+                       if (j==2)
+                               n = n*10 + c - '0';
+               }
+       } while (n != uid);
+       buf[i++] = '\0';
+       lastuid = uid;
+       return(0);
+}
+
+long
+nblock(size)
+long size;
+{
+       return((size+511)>>9);
+}
+
+int    m1[] = { 1, S_IREAD>>0, 'r', '-' };
+int    m2[] = { 1, S_IWRITE>>0, 'w', '-' };
+int    m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' };
+int    m4[] = { 1, S_IREAD>>3, 'r', '-' };
+int    m5[] = { 1, S_IWRITE>>3, 'w', '-' };
+int    m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' };
+int    m7[] = { 1, S_IREAD>>6, 'r', '-' };
+int    m8[] = { 1, S_IWRITE>>6, 'w', '-' };
+int    m9[] = { 2, S_ISVTX, 't', S_IEXEC>>6, 'x', '-' };
+
+int    *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
+
+pmode(aflag)
+{
+       register int **mp;
+
+       flags = aflag;
+       for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)
+               select(*mp++);
+}
+
+select(pairp)
+register int *pairp;
+{
+       register int n;
+
+       n = *pairp++;
+       while (--n>=0 && (flags&*pairp++)==0)
+               pairp++;
+       putchar(*pairp);
+}
+
+char *
+makename(dir, file)
+char *dir, *file;
+{
+       static char dfile[100];
+       register char *dp, *fp;
+       register int i;
+
+       dp = dfile;
+       fp = dir;
+       while (*fp)
+               *dp++ = *fp++;
+       *dp++ = '/';
+       fp = file;
+       for (i=0; i<DIRSIZ; i++)
+               *dp++ = *fp++;
+       *dp = 0;
+       return(dfile);
+}
+
+readdir(dir)
+char *dir;
+{
+       static struct direct dentry;
+       register int j;
+       register struct lbuf *ep;
+
+       if ((dirf = fopen(dir, "r")) == NULL) {
+               printf("%s unreadable\n", dir);
+               return;
+       }
+       tblocks = 0;
+       for(;;) {
+               if (fread((char *)&dentry, sizeof(dentry), 1, dirf) != 1)
+                       break;
+               if (dentry.d_ino==0
+                || aflg==0 && dentry.d_name[0]=='.' &&  (dentry.d_name[1]=='\0'
+                       || dentry.d_name[1]=='.' && dentry.d_name[2]=='\0'))
+                       continue;
+               ep = gstat(makename(dir, dentry.d_name), 0);
+               if (ep==NULL)
+                       continue;
+               if (ep->lnum != -1)
+                       ep->lnum = dentry.d_ino;
+               for (j=0; j<DIRSIZ; j++)
+                       ep->ln.lname[j] = dentry.d_name[j];
+       }
+       fclose(dirf);
+}
+
+struct lbuf *
+gstat(file, argfl)
+char *file;
+{
+       struct stat statb;
+       register struct lbuf *rep;
+       static int nomocore;
+
+       if (nomocore)
+               return(NULL);
+       rep = (struct lbuf *)malloc(sizeof(struct lbuf));
+       if (rep==NULL) {
+               fprintf(stderr, "ls: out of memory\n");
+               nomocore = 1;
+               return(NULL);
+       }
+       if (lastp >= &flist[NFILES]) {
+               static int msg;
+               lastp--;
+               if (msg==0) {
+                       fprintf(stderr, "ls: too many files\n");
+                       msg++;
+               }
+       }
+       *lastp++ = rep;
+       rep->lflags = 0;
+       rep->lnum = 0;
+       rep->ltype = '-';
+       if (argfl || statreq) {
+               if (stat(file, &statb)<0) {
+                       printf("%s not found\n", file);
+                       statb.st_ino = -1;
+                       statb.st_size = 0;
+                       statb.st_mode = 0;
+                       if (argfl) {
+                               lastp--;
+                               return(0);
+                       }
+               }
+               rep->lnum = statb.st_ino;
+               rep->lsize = statb.st_size;
+               switch(statb.st_mode&S_IFMT) {
+
+               case S_IFDIR:
+                       rep->ltype = 'd';
+                       break;
+
+               case S_IFBLK:
+                       rep->ltype = 'b';
+                       rep->lsize = statb.st_rdev;
+                       break;
+
+               case S_IFCHR:
+                       rep->ltype = 'c';
+                       rep->lsize = statb.st_rdev;
+                       break;
+               }
+               rep->lflags = statb.st_mode & ~S_IFMT;
+               rep->luid = statb.st_uid;
+               rep->lgid = statb.st_gid;
+               rep->lnl = statb.st_nlink;
+               if(uflg)
+                       rep->lmtime = statb.st_atime;
+               else if (cflg)
+                       rep->lmtime = statb.st_ctime;
+               else
+                       rep->lmtime = statb.st_mtime;
+               tblocks += nblock(statb.st_size);
+       }
+       return(rep);
+}
+
+compar(pp1, pp2)
+struct lbuf **pp1, **pp2;
+{
+       register struct lbuf *p1, *p2;
+
+       p1 = *pp1;
+       p2 = *pp2;
+       if (dflg==0) {
+               if (p1->lflags&ISARG && p1->ltype=='d') {
+                       if (!(p2->lflags&ISARG && p2->ltype=='d'))
+                               return(1);
+               } else {
+                       if (p2->lflags&ISARG && p2->ltype=='d')
+                               return(-1);
+               }
+       }
+       if (tflg) {
+               if(p2->lmtime == p1->lmtime)
+                       return(0);
+               if(p2->lmtime > p1->lmtime)
+                       return(rflg);
+               return(-rflg);
+       }
+       return(rflg * strcmp(p1->lflags&ISARG? p1->ln.namep: p1->ln.lname,
+                               p2->lflags&ISARG? p2->ln.namep: p2->ln.lname));
+}
diff --git a/usr/src/cmd/makekey.c b/usr/src/cmd/makekey.c
new file mode 100644 (file)
index 0000000..1640e51
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * You send it 10 bytes.
+ * It sends you 13 bytes.
+ * The transformation is expensive to perform
+ * (a significant part of a second).
+ */
+
+char   *crypt();
+
+main()
+{
+       char key[8];
+       char salt[2];
+       
+       read(0, key, 8);
+       read(0, salt, 2);
+       write(1, crypt(key, salt), 13);
+       return(0);
+}
diff --git a/usr/src/cmd/man/man.sh b/usr/src/cmd/man/man.sh
new file mode 100755 (executable)
index 0000000..28a4218
--- /dev/null
@@ -0,0 +1,62 @@
+cmd= sec= fil= opt= i= all=
+cmd=n sec=\?
+cd /usr/man
+for i
+do
+       case $i in
+
+       [1-8])
+               sec=$i ;;
+       -n)
+               cmd=n ;;
+       -t)
+               cmd=t ;;
+       -k)
+               cmd=k ;;
+       -e | -et | -te)
+               cmd=e ;;
+       -ek | -ke)
+               cmd=ek ;;
+       -ne | -en)
+               cmd=ne ;;
+
+       -w)
+               cmd=where ;;
+       -*)
+               opt="$opt $i" ;;
+
+       *)
+               fil=`echo man$sec/$i.*`
+               case $fil in
+               man7/eqnchar.7)
+                       all="$all /usr/pub/eqnchar $fil" ;;
+
+               *\*)
+                       echo $i not found 1>&2 ;;
+               *)
+                       all="$all $fil" ;;
+               esac
+       esac
+done
+case $all in
+       "")
+               exit ;;
+esac
+case $cmd in
+
+n)
+       nroff $opt -man $all ;;
+ne)
+       neqn $all | nroff $opt -man ;;
+t)
+       troff $opt -man $all ;;
+k)
+       troff -t $opt -man $all | tc ;;
+e)
+       eqn $all | troff $opt -man ;;
+ek)
+       eqn $all | troff -t $opt -man | tc ;;
+
+where)
+       echo $all ;;
+esac
diff --git a/usr/src/cmd/mkdir.c b/usr/src/cmd/mkdir.c
new file mode 100644 (file)
index 0000000..0fb6f97
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+** make directory
+*/
+
+#include       <signal.h>
+#include       <stdio.h>
+
+int    Errors = 0;
+char   *strcat();
+char   *strcpy();
+
+main(argc, argv)
+char *argv[];
+{
+
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       signal(SIGPIPE, SIG_IGN);
+       signal(SIGTERM, SIG_IGN);
+
+       if(argc < 2) {
+               fprintf(stderr, "mkdir: arg count\n");
+               exit(1);
+       }
+       while(--argc)
+               mkdir(*++argv);
+       exit(Errors!=0);
+}
+
+mkdir(d)
+char *d;
+{
+       char pname[128], dname[128];
+       register i, slash = 0;
+
+       pname[0] = '\0';
+       for(i = 0; d[i]; ++i)
+               if(d[i] == '/')
+                       slash = i + 1;
+       if(slash)
+               strncpy(pname, d, slash);
+       strcpy(pname+slash, ".");
+       if (access(pname, 02)) {
+               fprintf(stderr,"mkdir: cannot access %s\n", pname);
+               ++Errors;
+               return;
+       }
+       if ((mknod(d, 040777, 0)) < 0) {
+               fprintf(stderr,"mkdir: cannot make directory %s\n", d);
+               ++Errors;
+               return;
+       }
+       chown(d, getuid(), getgid());
+       strcpy(dname, d);
+       strcat(dname, "/.");
+       if((link(d, dname)) < 0) {
+               fprintf(stderr, "mkdir: cannot link %s\n", dname);
+               unlink(d);
+               ++Errors;
+               return;
+       }
+       strcat(dname, ".");
+       if((link(pname, dname)) < 0) {
+               fprintf(stderr, "mkdir: cannot link %s\n",dname);
+               dname[strlen(dname)] = '\0';
+               unlink(dname);
+               unlink(d);
+               ++Errors;
+       }
+}
diff --git a/usr/src/cmd/mknod.c b/usr/src/cmd/mknod.c
new file mode 100644 (file)
index 0000000..4fccc28
--- /dev/null
@@ -0,0 +1,42 @@
+main(argc, argv)
+int argc;
+char **argv;
+{
+       int m, a, b;
+
+       if(argc != 5) {
+               printf("arg count\n");
+               goto usage;
+       }
+       if(*argv[2] == 'b')
+               m = 060666; else
+       if(*argv[2] == 'c')
+               m = 020666; else
+               goto usage;
+       a = number(argv[3]);
+       if(a < 0)
+               goto usage;
+       b = number(argv[4]);
+       if(b < 0)
+               goto usage;
+       if(mknod(argv[1], m, (a<<8)|b) < 0)
+               perror("mknod");
+       exit(0);
+
+usage:
+       printf("usage: mknod name b/c major minor\n");
+}
+
+number(s)
+char *s;
+{
+       int n, c;
+
+       n = 0;
+       while(c = *s++) {
+               if(c<'0' || c>'9')
+                       return(-1);
+               n = n*10 + c-'0';
+       }
+       return(n);
+}
diff --git a/usr/src/cmd/mount.c b/usr/src/cmd/mount.c
new file mode 100644 (file)
index 0000000..6ec1d00
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+#define        NMOUNT  16
+#define        NAMSIZ  32
+
+struct mtab {
+       char    file[NAMSIZ];
+       char    spec[NAMSIZ];
+} mtab[NMOUNT];
+
+main(argc, argv)
+char **argv;
+{
+       register int ro;
+       register struct mtab *mp;
+       register char *np;
+       int mf;
+
+       mf = open("/etc/mtab", 0);
+       read(mf, (char *)mtab, NMOUNT*2*NAMSIZ);
+       if (argc==1) {
+               for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
+                       if (mp->file[0])
+                               printf("%s on %s\n", mp->spec, mp->file);
+               exit(0);
+       }
+       if(argc < 3) {
+               fprintf(stderr,"arg count\n");
+               exit(1);
+       }
+       ro = 0;
+       if(argc > 3)
+               ro++;
+       if(mount(argv[1], argv[2], ro) < 0) {
+               perror("mount");
+               exit(1);
+       }
+       np = argv[1];
+       while(*np++)
+               ;
+       np--;
+       while(*--np == '/')
+               *np = '\0';
+       while(np > argv[1] && *--np != '/')
+               ;
+       if(*np == '/')
+               np++;
+       argv[1] = np;
+       for (mp = mtab; mp < &mtab[NMOUNT]; mp++) {
+               if (mp->file[0] == 0) {
+                       for (np = mp->spec; np < &mp->spec[NAMSIZ-1];)
+                               if ((*np++ = *argv[1]++) == 0)
+                                       argv[1]--;
+                       for (np = mp->file; np < &mp->file[NAMSIZ-1];)
+                               if ((*np++ = *argv[2]++) == 0)
+                                       argv[2]--;
+                       mp = &mtab[NMOUNT];
+                       while ((--mp)->file[0] == 0);
+                       mf = creat("/etc/mtab", 0644);
+                       write(mf, (char *)mtab, (mp-mtab+1)*2*NAMSIZ);
+                       exit(0);
+               }
+       }
+       exit(0);
+}
diff --git a/usr/src/cmd/mv.c b/usr/src/cmd/mv.c
new file mode 100644 (file)
index 0000000..0e2b701
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * mv file1 file2
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+#include <signal.h>
+
+#define        DOT     "."
+#define        DOTDOT  ".."
+#define        DELIM   '/'
+#define SDELIM "/"
+#define        MAXN    100
+#define MODEBITS 07777
+#define ROOTINO 2
+
+char   *pname();
+char   *sprintf();
+char   *dname();
+struct stat s1, s2;
+
+main(argc, argv)
+register char *argv[];
+{
+       register i, r;
+
+       if (argc < 3)
+               goto usage;
+       if (stat(argv[1], &s1) < 0) {
+               fprintf(stderr, "mv: cannot access %s\n", argv[1]);
+               return(1);
+       }
+       if ((s1.st_mode & S_IFMT) == S_IFDIR) {
+               if (argc != 3)
+                       goto usage;
+               return mvdir(argv[1], argv[2]);
+       }
+       setuid(getuid());
+       if (argc > 3)
+               if (stat(argv[argc-1], &s2) < 0 || (s2.st_mode & S_IFMT) != S_IFDIR)
+                       goto usage;
+       r = 0;
+       for (i=1; i<argc-1; i++)
+               r |= move(argv[i], argv[argc-1]);
+       return(r);
+usage:
+       fprintf(stderr, "usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1\n");
+       return(1);
+}
+
+move(source, target)
+char *source, *target;
+{
+       register c, i;
+       int     status;
+       char    buf[MAXN];
+
+       if (stat(source, &s1) < 0) {
+               fprintf(stderr, "mv: cannot access %s\n", source);
+               return(1);
+       }
+       if ((s1.st_mode & S_IFMT) == S_IFDIR) {
+               fprintf(stderr, "mv: directory rename only\n");
+               return(1);
+       }
+       if (stat(target, &s2) >= 0) {
+               if ((s2.st_mode & S_IFMT) == S_IFDIR) {
+                       sprintf(buf, "%s/%s", target, dname(source));
+                       target = buf;
+               }
+               if (stat(target, &s2) >= 0) {
+                       if ((s2.st_mode & S_IFMT) == S_IFDIR) {
+                               fprintf(stderr, "mv: %s is a directory\n", target);
+                               return(1);
+                       }
+                       if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) {
+                               fprintf(stderr, "mv: %s and %s are identical\n",
+                                               source, target);
+                               return(1);
+                       }
+                       if (access(target, 2) < 0 && isatty(fileno(stdin))) {
+                               fprintf(stderr, "mv: %s: %o mode ", target,
+                                       s2.st_mode & MODEBITS);
+                               i = c = getchar();
+                               while (c != '\n' && c != EOF)
+                                       c = getchar();
+                               if (i != 'y')
+                                       return(1);
+                       }
+                       if (unlink(target) < 0) {
+                               fprintf(stderr, "mv: cannot unlink %s\n", target);
+                               return(1);
+                       }
+               }
+       }
+       if (link(source, target) < 0) {
+               i = fork();
+               if (i == -1) {
+                       fprintf(stderr, "mv: try again\n");
+                       return(1);
+               }
+               if (i == 0) {
+                       execl("/bin/cp", "cp", source, target, 0);
+                       fprintf(stderr, "mv: cannot exec cp\n");
+                       exit(1);
+               }
+               while ((c = wait(&status)) != i && c != -1)
+                       ;
+               if (status != 0)
+                       return(1);
+               utime(target, &s1.st_atime);
+       }
+       if (unlink(source) < 0) {
+               fprintf(stderr, "mv: cannot unlink %s\n", source);
+               return(1);
+       }
+       return(0);
+}
+
+mvdir(source, target)
+char *source, *target;
+{
+       register char *p;
+       register i;
+       char buf[MAXN];
+
+       if (stat(target, &s2) >= 0) {
+               if ((s2.st_mode&S_IFMT) != S_IFDIR) {
+                       fprintf(stderr, "mv: %s exists\n", target);
+                       return(1);
+               }
+               if (strlen(target) > MAXN-DIRSIZ-2) {
+                       fprintf(stderr, "mv :target name too long\n");
+                       return(1);
+               }
+               strcpy(buf, target);
+               target = buf;
+               strcat(buf, SDELIM);
+               strcat(buf, dname(source));
+               if (stat(target, &s2) >= 0) {
+                       fprintf(stderr, "mv: %s exists\n", buf);
+                       return(1);
+               }
+       }
+       if (strcmp(source, target) == 0) {
+               fprintf(stderr, "mv: ?? source == target, source exists and target doesnt\n");
+               return(1);
+       }
+       p = dname(source);
+       if (!strcmp(p, DOT) || !strcmp(p, DOTDOT) || !strcmp(p, "") || p[strlen(p)-1]=='/') {
+               fprintf(stderr, "mv: cannot rename %s\n", p);
+               return(1);
+       }
+       if (stat(pname(source), &s1) < 0 || stat(pname(target), &s2) < 0) {
+               fprintf(stderr, "mv: cannot locate parent\n");
+               return(1);
+       }
+       if (access(pname(target), 2) < 0) {
+               fprintf(stderr, "mv: no write access to %s\n", pname(target));
+               return(1);
+       }
+       if (access(pname(source), 2) < 0) {
+               fprintf(stderr, "mv: no write access to %s\n", pname(source));
+               return(1);
+       }
+       if (access(source, 2) < 0) {
+               fprintf(stderr, "mv: no write access to %s\n", source);
+               return(1);
+       }
+       if (s1.st_dev != s2.st_dev) {
+               fprintf(stderr, "mv: cannot move directories across devices\n");
+               return(1);
+       }
+       if (s1.st_ino != s2.st_ino) {
+               char dst[MAXN+5];
+
+               if (chkdot(source) || chkdot(target)) {
+                       fprintf(stderr, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT);
+                       return(1);
+               }
+               stat(source, &s1);
+               if (check(pname(target), s1.st_ino))
+                       return(1);
+               for (i = 1; i <= NSIG; i++)
+                       signal(i, SIG_IGN);
+               if (link(source, target) < 0) {
+                       fprintf(stderr, "mv: cannot link %s to %s\n", target, source);
+                       return(1);
+               }
+               if (unlink(source) < 0) {
+                       fprintf(stderr, "mv: %s: cannot unlink\n", source);
+                       unlink(target);
+                       return(1);
+               }
+               strcat(dst, target);
+               strcat(dst, "/");
+               strcat(dst, DOTDOT);
+               if (unlink(dst) < 0) {
+                       fprintf(stderr, "mv: %s: cannot unlink\n", dst);
+                       if (link(target, source) >= 0)
+                               unlink(target);
+                       return(1);
+               }
+               if (link(pname(target), dst) < 0) {
+                       fprintf(stderr, "mv: cannot link %s to %s\n",
+                               dst, pname(target));
+                       if (link(pname(source), dst) >= 0)
+                               if (link(target, source) >= 0)
+                                       unlink(target);
+                       return(1);
+               }
+               return(0);
+       }
+       if (link(source, target) < 0) {
+               fprintf(stderr, "mv: cannot link %s and %s\n",
+                       source, target);
+               return(1);
+       }
+       if (unlink(source) < 0) {
+               fprintf(stderr, "mv: ?? cannot unlink %s\n", source);
+               return(1);
+       }
+       return(0);
+}
+
+char *
+pname(name)
+register char *name;
+{
+       register c;
+       register char *p, *q;
+       static  char buf[MAXN];
+
+       p = q = buf;
+       while (c = *p++ = *name++)
+               if (c == DELIM)
+                       q = p-1;
+       if (q == buf && *q == DELIM)
+               q++;
+       *q = 0;
+       return buf[0]? buf : DOT;
+}
+
+char *
+dname(name)
+register char *name;
+{
+       register char *p;
+
+       p = name;
+       while (*p)
+               if (*p++ == DELIM && *p)
+                       name = p;
+       return name;
+}
+
+check(spth, dinode)
+char *spth;
+ino_t dinode;
+{
+       char nspth[MAXN];
+       struct stat sbuf;
+
+       sbuf.st_ino = 0;
+
+       strcpy(nspth, spth);
+       while (sbuf.st_ino != ROOTINO) {
+               if (stat(nspth, &sbuf) < 0) {
+                       fprintf(stderr, "mv: cannot access %s\n", nspth);
+                       return(1);
+               }
+               if (sbuf.st_ino == dinode) {
+                       fprintf(stderr, "mv: cannot move a directory into itself\n");
+                       return(1);
+               }
+               if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) {
+                       fprintf(stderr, "mv: name too long\n");
+                       return(1);
+               }
+               strcat(nspth, SDELIM);
+               strcat(nspth, DOTDOT);
+       }
+       return(0);
+}
+
+chkdot(s)
+register char *s;
+{
+       do {
+               if (strcmp(dname(s), DOTDOT) == 0)
+                       return(1);
+               s = pname(s);
+       } while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0);
+       return(0);
+}
diff --git a/usr/src/cmd/ncheck.c b/usr/src/cmd/ncheck.c
new file mode 100644 (file)
index 0000000..3bbe4a2
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * ncheck -- obtain file names from reading filesystem
+ */
+
+#define        NI      16
+#define        NB      100
+#define        HSIZE   2503
+#define        NDIR    (BSIZE/sizeof(struct direct))
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/inode.h>
+#include <sys/ino.h>
+#include <sys/dir.h>
+#include <sys/filsys.h>
+#include <sys/fblk.h>
+
+struct filsys  sblock;
+struct dinode  itab[INOPB*NI];
+daddr_t        iaddr[NADDR];
+ino_t  ilist[NB];
+struct htab
+{
+       ino_t   h_ino;
+       ino_t   h_pino;
+       char    h_name[DIRSIZ];
+} htab[HSIZE];
+
+int    aflg;
+int    sflg;
+int    fi;
+ino_t  ino;
+int    nhent;
+int    nxfile;
+
+int    nerror;
+daddr_t        bmap();
+long   atol();
+struct htab *lookup();
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       long n;
+
+       while (--argc) {
+               argv++;
+               if (**argv=='-')
+               switch ((*argv)[1]) {
+
+               case 'a':
+                       aflg++;
+                       continue;
+
+               case 'i':
+                       for(i=0; i<NB; i++) {
+                               n = atol(argv[1]);
+                               if(n == 0)
+                                       break;
+                               ilist[i] = n;
+                               nxfile = i;
+                               argv++;
+                               argc--;
+                       }
+                       continue;
+
+               case 's':
+                       sflg++;
+                       continue;
+
+               default:
+                       fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
+                       nerror++;
+               }
+               check(*argv);
+       }
+       return(nerror);
+}
+
+check(file)
+char *file;
+{
+       register i, j;
+       ino_t mino;
+
+       fi = open(file, 0);
+       if(fi < 0) {
+               fprintf(stderr, "ncheck: cannot open %s\n", file);
+               nerror++;
+               return;
+       }
+       nhent = 0;
+       printf("%s:\n", file);
+       sync();
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       mino = (sblock.s_isize-2) * INOPB;
+       ino = 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]);
+               }
+       }
+       ilist[nxfile+1] = 0;
+       ino = 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++;
+                       pass2(&itab[j]);
+               }
+       }
+       ino = 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++;
+                       pass3(&itab[j]);
+               }
+       }
+}
+
+pass1(ip)
+register struct dinode *ip;
+{
+       if((ip->di_mode & IFMT) != IFDIR) {
+               if (sflg==0 || nxfile>=NB)
+                       return;
+               if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
+                 || ip->di_mode&(ISUID|ISGID))
+                       ilist[nxfile++] = ino;
+                       return;
+       }
+       lookup(ino, 1);
+}
+
+pass2(ip)
+register struct dinode *ip;
+{
+       struct direct dbuf[NDIR];
+       long doff;
+       struct direct *dp;
+       register i, j;
+       int k;
+       struct htab *hp;
+       daddr_t d;
+       ino_t kno;
+
+       if((ip->di_mode&IFMT) != IFDIR)
+               return;
+       l3tol(iaddr, ip->di_addr, NADDR);
+       doff = 0;
+       for(i=0;; i++) {
+               if(doff >= ip->di_size)
+                       break;
+               d = bmap(i);
+               if(d == 0)
+                       break;
+               bread(d, (char *)dbuf, sizeof(dbuf));
+               for(j=0; j<NDIR; j++) {
+                       if(doff >= ip->di_size)
+                               break;
+                       doff += sizeof(struct direct);
+                       dp = dbuf+j;
+                       kno = dp->d_ino;
+                       if(kno == 0)
+                               continue;
+                       hp = lookup(kno, 0);
+                       if(hp == 0)
+                               continue;
+                       if(dotname(dp))
+                               continue;
+                       hp->h_pino = ino;
+                       for(k=0; k<DIRSIZ; k++)
+                               hp->h_name[k] = dp->d_name[k];
+               }
+       }
+}
+
+pass3(ip)
+register struct dinode *ip;
+{
+       struct direct dbuf[NDIR];
+       long doff;
+       struct direct *dp;
+       register i, j;
+       int k;
+       daddr_t d;
+       ino_t kno;
+
+       if((ip->di_mode&IFMT) != IFDIR)
+               return;
+       l3tol(iaddr, ip->di_addr, NADDR);
+       doff = 0;
+       for(i=0;; i++) {
+               if(doff >= ip->di_size)
+                       break;
+               d = bmap(i);
+               if(d == 0)
+                       break;
+               bread(d, (char *)dbuf, sizeof(dbuf));
+               for(j=0; j<NDIR; j++) {
+                       if(doff >= ip->di_size)
+                               break;
+                       doff += sizeof(struct direct);
+                       dp = dbuf+j;
+                       kno = dp->d_ino;
+                       if(kno == 0)
+                               continue;
+                       if(aflg==0 && dotname(dp))
+                               continue;
+                       if(ilist[0] == 0)
+                               goto pr;
+                       for(k=0; ilist[k] != 0; k++)
+                               if(ilist[k] == kno)
+                                       goto pr;
+                       continue;
+               pr:
+                       printf("%u      ", kno);
+                       pname(ino, 0);
+                       printf("/%.14s", dp->d_name);
+                       if (lookup(kno, 0))
+                               printf("/.");
+                       printf("\n");
+               }
+       }
+}
+
+dotname(dp)
+register struct direct *dp;
+{
+
+       if (dp->d_name[0]=='.')
+               if (dp->d_name[1]==0 || (dp->d_name[1]=='.' && dp->d_name[2]==0))
+                       return(1);
+       return(0);
+}
+
+pname(i, lev)
+ino_t i;
+{
+       register struct htab *hp;
+
+       if (i==ROOTINO)
+               return;
+       if ((hp = lookup(i, 0)) == 0) {
+               printf("???");
+               return;
+       }
+       if (lev > 10) {
+               printf("...");
+               return;
+       }
+       pname(hp->h_pino, ++lev);
+       printf("/%.14s", hp->h_name);
+}
+
+struct htab *
+lookup(i, ef)
+ino_t i;
+{
+       register struct htab *hp;
+
+       for (hp = &htab[i%HSIZE]; hp->h_ino;) {
+               if (hp->h_ino==i)
+                       return(hp);
+               if (++hp >= &htab[HSIZE])
+                       hp = htab;
+       }
+       if (ef==0)
+               return(0);
+       if (++nhent >= HSIZE) {
+               fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");
+               exit(1);
+       }
+       hp->h_ino = i;
+       return(hp);
+}
+
+bread(bno, buf, cnt)
+daddr_t bno;
+char *buf;
+{
+       register i;
+
+       lseek(fi, bno*BSIZE, 0);
+       if (read(fi, buf, cnt) != cnt) {
+               fprintf(stderr, "ncheck: read error %d\n", bno);
+               for(i=0; i<BSIZE; i++)
+                       buf[i] = 0;
+       }
+}
+
+daddr_t
+bmap(i)
+{
+       daddr_t ibuf[NINDIR];
+
+       if(i < NADDR-3)
+               return(iaddr[i]);
+       i -= NADDR-3;
+       if(i > NINDIR) {
+               fprintf(stderr, "ncheck: %u - huge directory\n", ino);
+               return((daddr_t)0);
+       }
+       bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf));
+       return(ibuf[i]);
+}
diff --git a/usr/src/cmd/nice.c b/usr/src/cmd/nice.c
new file mode 100644 (file)
index 0000000..ed22a93
--- /dev/null
@@ -0,0 +1,26 @@
+/* nice */
+
+#include <stdio.h>
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       int nicarg = 10;
+       extern errno;
+       extern char *sys_errlist[];
+
+       if(argc > 1 && argv[1][0] == '-') {
+               nicarg = atoi(&argv[1][1]);
+               argc--;
+               argv++;
+       }
+       if(argc < 2) {
+               fputs("usage: nice [ -n ] command\n", stderr);
+               exit(1);
+       }
+       nice(nicarg);
+       execvp(argv[1], &argv[1]);
+       fprintf(stderr, "%s: %s\n", sys_errlist[errno], argv[1]);
+       exit(1);
+}
diff --git a/usr/src/cmd/nohup.sh b/usr/src/cmd/nohup.sh
new file mode 100755 (executable)
index 0000000..6b590e9
--- /dev/null
@@ -0,0 +1,7 @@
+trap "" 1 15
+if test -t 2>&1  ; then
+       echo "Sending output to 'nohup.out'"
+       exec nice -5 $* >>nohup.out 2>&1
+else
+       exec nice -5 $* 2>&1
+fi
diff --git a/usr/src/cmd/od.c b/usr/src/cmd/od.c
new file mode 100644 (file)
index 0000000..f0809c9
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * od -- octal (also hex, decimal, and character) dump
+ */
+
+#include <stdio.h>
+
+unsigned short word[8];
+unsigned short lastword[8];
+int    conv;
+int    base =  010;
+int    max;
+long   addr;
+
+main(argc, argv)
+char **argv;
+{
+       register char *p;
+       register n, f, same;
+
+
+       argv++;
+       f = 0;
+       if(argc > 1) {
+               p = *argv;
+               if(*p == '-') {
+                       while(*p != '\0') {
+                               switch(*p++) {
+                               case 'o':
+                                       conv |= 001;
+                                       f = 6;
+                                       break;
+                               case 'd':
+                                       conv |= 002;
+                                       f = 5;
+                                       break;
+                               case 'x':
+                               case 'h':
+                                       conv |= 010;
+                                       f = 4;
+                                       break;
+                               case 'c':
+                                       conv |= 020;
+                                       f = 7;
+                                       break;
+                               case 'b':
+                                       conv |= 040;
+                                       f = 7;
+                                       break;
+                               }
+                               if(f > max)
+                                       max = f;
+                       }
+                       argc--;
+                       argv++;
+               }
+       }
+       if(!conv) {
+               max = 6;
+               conv = 1;
+       }
+       if(argc > 1)
+       if(**argv != '+') {
+               if (freopen(*argv, "r", stdin) == NULL) {
+                       printf("cannot open %s\n", *argv);
+                       exit(1);
+               }
+               argv++;
+               argc--;
+       }
+       if(argc > 1)
+               offset(*argv);
+
+       same = -1;
+       for ( ; (n = fread((char *)word, 1, sizeof(word), stdin)) > 0; addr += n) {
+               if (same>=0) {
+                       for (f=0; f<8; f++)
+                               if (lastword[f] != word[f])
+                                       goto notsame;
+                       if (same==0) {
+                               printf("*\n");
+                               same = 1;
+                       }
+                       continue;
+               }
+       notsame:
+               line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0]));
+               same = 0;
+               for (f=0; f<8; f++)
+                       lastword[f] = word[f];
+               for (f=0; f<8; f++)
+                       word[f] = 0;
+       }
+       putn(addr, base, 7);
+       putchar('\n');
+}
+
+line(a, w, n)
+long a;
+unsigned short *w;
+{
+       register i, f, c;
+
+       f = 1;
+       for(c=1; c; c<<=1) {
+               if((c&conv) == 0)
+                       continue;
+               if(f) {
+                       putn(a, base, 7);
+                       putchar(' ');
+                       f = 0;
+               } else
+                       putchar('\t');
+               for (i=0; i<n; i++) {
+                       putx(w[i], c);
+                       putchar(i==n-1? '\n': ' ');
+               }
+       }
+}
+
+putx(n, c)
+unsigned n;
+{
+
+       switch(c) {
+       case 001:
+               pre(6);
+               putn((long)n, 8, 6);
+               break;
+       case 002:
+               pre(5);
+               putn((long)n, 10, 5);
+               break;
+       case 010:
+               pre(4);
+               putn((long)n, 16, 4);
+               break;
+       case 020:
+               pre(7);
+               {
+                       unsigned short sn = n;
+                       cput(*(char *)&sn);
+                       putchar(' ');
+                       cput(*((char *)&sn + 1));
+                       break;
+               }
+       case 040:
+               pre(7);
+               {
+                       unsigned short sn = n;
+                       putn((long)(*(char *)&sn)&0377, 8, 3);
+                       putchar(' ');
+                       putn((long)(*((char *)&sn + 1))&0377, 8, 3);
+                       break;
+               }
+       }
+}
+
+cput(c)
+{
+       c &= 0377;
+       if(c>037 && c<0177) {
+               printf("  ");
+               putchar(c);
+               return;
+       }
+       switch(c) {
+       case '\0':
+               printf(" \\0");
+               break;
+       case '\b':
+               printf(" \\b");
+               break;
+       case '\f':
+               printf(" \\f");
+               break;
+       case '\n':
+               printf(" \\n");
+               break;
+       case '\r':
+               printf(" \\r");
+               break;
+       case '\t':
+               printf(" \\t");
+               break;
+       default:
+               putn((long)c, 8, 3);
+       }
+}
+
+putn(n, b, c)
+long n;
+{
+       register d;
+
+       if(!c)
+               return;
+       putn(n/b, b, c-1);
+       d = n%b;
+       if (d > 9)
+               putchar(d-10+'a');
+       else
+               putchar(d+'0');
+}
+
+pre(n)
+{
+       int i;
+
+       for(i=n; i<max; i++)
+               putchar(' ');
+}
+
+offset(s)
+register char *s;
+{
+       register char *p;
+       long a;
+       register int d;
+
+       if (*s=='+')
+               s++;
+       if (*s=='x') {
+               s++;
+               base = 16;
+       } else if (*s=='0' && s[1]=='x') {
+               s += 2;
+               base = 16;
+       } else if (*s == '0')
+               base = 8;
+       p = s;
+       while(*p) {
+               if (*p++=='.')
+                       base = 10;
+       }
+       for (a=0; *s; s++) {
+               d = *s;
+               if(d>='0' && d<='9')
+                       a = a*base + d - '0';
+               else if (d>='a' && d<='f' && base==16)
+                       a = a*base + d + 10 - 'a';
+               else
+                       break;
+       }
+       if (*s == '.')
+               s++;
+       if(*s=='b' || *s=='B')
+               a *= 512;
+       fseek(stdin, a, 0);
+       addr = a;
+}
diff --git a/usr/src/cmd/pr.c b/usr/src/cmd/pr.c
new file mode 100644 (file)
index 0000000..880661e
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ *   print file with headings
+ *  2+head+2+page[56]+5
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+int    ncol    = 1;
+char   *header;
+int    col;
+int    icol;
+FILE   *file;
+char   *bufp;
+#define        BUFS    6720
+char   buffer[BUFS];   /* for multi-column output */
+char   obuf[BUFSIZ];
+#define        FF      014
+int    line;
+char   *colp[72];
+int    nofile;
+char   isclosed[10];
+FILE   *ifile[10];
+char   **lastarg;
+int    peekc;
+int    fpage;
+int    page;
+int    colw;
+int    nspace;
+int    width   = 72;
+int    length  = 66;
+int    plength = 61;
+int    margin  = 10;
+int    ntflg;
+int    mflg;
+int    tabc;
+char   *tty;
+int    mode;
+char   *ttyname();
+char   *ctime();
+
+main(argc, argv)
+char **argv;
+{
+       int nfdone;
+       int onintr();
+
+       setbuf(stdout, obuf);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, onintr);
+       lastarg = &argv[argc-1];
+       fixtty();
+       for (nfdone=0; argc>1; argc--) {
+               argv++;
+               if (**argv == '-') {
+                       switch (*++*argv) {
+                       case 'h':
+                               if (argc>=2) {
+                                       header = *++argv;
+                                       argc--;
+                               }
+                               continue;
+
+                       case 't':
+                               ntflg++;
+                               continue;
+
+                       case 'l':
+                               length = atoi(++*argv);
+                               continue;
+
+                       case 'w':
+                               width = atoi(++*argv);
+                               continue;
+
+                       case 's':
+                               if (*++*argv)
+                                       tabc = **argv;
+                               else
+                                       tabc = '\t';
+                               continue;
+
+                       case 'm':
+                               mflg++;
+                               continue;
+
+                       default:
+                               ncol = atoi(*argv);
+                               continue;
+                       }
+               } else if (**argv == '+') {
+                       fpage = atoi(++*argv);
+               } else {
+                       print(*argv, argv);
+                       nfdone++;
+                       if (mflg)
+                               break;
+               }
+       }
+       if (nfdone==0)
+               print((char *)0, (char **)0);
+       done();
+}
+
+done()
+{
+
+       if (tty)
+               chmod(tty, mode);
+       exit(0);
+}
+
+onintr()
+{
+
+       if (tty)
+               chmod(tty, mode);
+       _exit(1);
+}
+
+fixtty()
+{
+       struct stat sbuf;
+
+       tty = ttyname(1);
+       if (tty == 0)
+               return;
+       stat(tty, &sbuf);
+       mode = sbuf.st_mode&0777;
+       chmod(tty, 0600);
+}
+
+print(fp, argp)
+char *fp;
+char **argp;
+{
+       extern char *sprintf();
+       struct stat sbuf;
+       register sncol;
+       register char *sheader;
+       register char *cbuf;
+       char linebuf[150], *cp;
+
+       if (ntflg)
+               margin = 0;
+       else
+               margin = 10;
+       if (length <= margin)
+               length = 66;
+       if (width <= 0)
+               width = 72;
+       if (ncol>72 || ncol>width) {
+               fprintf(stderr, "pr: No room for columns.\n");
+               done();
+       }
+       if (mflg) {
+               mopen(argp);
+               ncol = nofile;
+       }
+       colw = width/(ncol==0? 1 : ncol);
+       sncol = ncol;
+       sheader = header;
+       plength = length-5;
+       if (ntflg)
+               plength = length;
+       if (--ncol<0)
+               ncol = 0;
+       if (mflg)
+               fp = 0;
+       if (fp) {
+               if((file=fopen(fp, "r"))==NULL) {
+                       if (tty==NULL)
+                               fprintf(stderr, "pr: can't open %s\n", fp);
+                       ncol = sncol;
+                       header = sheader;
+                       return;
+               }
+               stat(fp, &sbuf);
+       } else {
+               file = stdin;
+               time(&sbuf.st_mtime);
+       }
+       if (header == 0)
+               header = fp?fp:"";
+       cbuf = ctime(&sbuf.st_mtime);
+       cbuf[16] = '\0';
+       cbuf[24] = '\0';
+       page = 1;
+       icol = 0;
+       colp[ncol] = bufp = buffer;
+       if (mflg==0)
+               nexbuf();
+       while (mflg&&nofile || (!mflg)&&tpgetc(ncol)>0) {
+               if (mflg==0) {
+                       colp[ncol]--;
+                       if (colp[ncol] < buffer)
+                               colp[ncol] = &buffer[BUFS];
+               }
+               line = 0;
+               if (ntflg==0) {
+                       sprintf(linebuf, "\n\n%s %s  %s Page %d\n\n\n",
+                               cbuf+4, cbuf+20, header, page);
+                       for(cp=linebuf;*cp;) put(*cp++);
+               }
+               putpage();
+               if (ntflg==0)
+                       while(line<length)
+                               put('\n');
+               page++;
+       }
+       fclose(file);
+       ncol = sncol;
+       header = sheader;
+}
+
+mopen(ap)
+char **ap;
+{
+       register char **p, *p1;
+
+       p = ap;
+       while((p1 = *p) && p++ <= lastarg) {
+               if((ifile[nofile]=fopen(p1, "r")) == NULL){
+                       isclosed[nofile] = 1;
+                       nofile--;
+               }
+               else
+                       isclosed[nofile] = 0;
+               if(++nofile>=10) {
+                       fprintf(stderr, "pr: Too many args\n");
+                       done();
+               }
+       }
+}
+
+putpage()
+{
+       register int lastcol, i, c;
+       int j;
+
+       if (ncol==0) {
+               while (line<plength) {
+                       while((c = tpgetc(0)) && c!='\n' && c!=FF)
+                               putcp(c);
+                       putcp('\n');
+                       line++;
+                       if (c==FF)
+                               break;
+               }
+               return;
+       }
+       colp[0] = colp[ncol];
+       if (mflg==0) for (i=1; i<=ncol; i++) {
+               colp[i] = colp[i-1];
+               for (j = margin; j<length; j++)
+                       while((c=tpgetc(i))!='\n')
+                               if (c==0)
+                                       break;
+       }
+       while (line<plength) {
+               lastcol = colw;
+               for (i=0; i<ncol; i++) {
+                       while ((c=pgetc(i)) && c!='\n')
+                               if (col<lastcol || tabc!=0)
+                                       put(c);
+                       if (c==0)
+                               continue;
+                       if (tabc)
+                               put(tabc);
+                       else while (col<lastcol)
+                               put(' ');
+                       lastcol += colw;
+               }
+               while ((c = pgetc(ncol)) && c!='\n')
+                       put(c);
+               put('\n');
+       }
+}
+
+nexbuf()
+{
+       register int n;
+       register char *rbufp;
+
+       rbufp = bufp;
+       n = &buffer[BUFS] - rbufp;
+       if (n>512)
+               n = 512;
+       if((n=fread(rbufp,1,n,file)) <= 0){
+               fclose(file);
+               *rbufp = 0376;
+       }
+       else {
+               rbufp += n;
+               if (rbufp >= &buffer[BUFS])
+                       rbufp = buffer;
+               *rbufp = 0375;
+       }
+       bufp = rbufp;
+}
+
+tpgetc(ai)
+{
+       register char **p;
+       register int c, i;
+
+       i = ai;
+       if (mflg) {
+               if((c=getc(ifile[i])) == EOF) {
+                       if (isclosed[i]==0) {
+                               isclosed[i] = 1;
+                               if (--nofile <= 0)
+                                       return(0);
+                       }
+                       return('\n');
+               }
+               if (c==FF && ncol>0)
+                       c = '\n';
+               return(c);
+       }
+loop:
+       c = **(p = &colp[i]) & 0377;
+       if (c == 0375) {
+               nexbuf();
+               c = **p & 0377;
+       }
+       if (c == 0376)
+               return(0);
+       (*p)++;
+       if (*p >= &buffer[BUFS])
+               *p = buffer;
+       if (c==0)
+               goto loop;
+       return(c);
+}
+
+pgetc(i)
+{
+       register int c;
+
+       if (peekc) {
+               c = peekc;
+               peekc = 0;
+       } else
+               c = tpgetc(i);
+       if (tabc)
+               return(c);
+       switch (c) {
+
+       case '\t':
+               icol++;
+               if ((icol&07) != 0)
+                       peekc = '\t';
+               return(' ');
+
+       case '\n':
+               icol = 0;
+               break;
+
+       case 010:
+       case 033:
+               icol--;
+               break;
+       }
+       if (c >= ' ')
+               icol++;
+       return(c);
+}
+put(ac)
+{
+       register int ns, c;
+
+       c = ac;
+       if (tabc) {
+               putcp(c);
+               if (c=='\n')
+                       line++;
+               return;
+       }
+       switch (c) {
+
+       case ' ':
+               nspace++;
+               col++;
+               return;
+
+       case '\n':
+               col = 0;
+               nspace = 0;
+               line++;
+               break;
+
+       case 010:
+       case 033:
+               if (--col<0)
+                       col = 0;
+               if (--nspace<0)
+                       nspace = 0;
+
+       }
+       while(nspace) {
+               if (nspace>2 && col > (ns=((col-nspace)|07))) {
+                       nspace = col-ns-1;
+                       putcp('\t');
+               } else {
+                       nspace--;
+                       putcp(' ');
+               }
+       }
+       if (c >= ' ')
+               col++;
+       putcp(c);
+}
+
+putcp(c)
+{
+       if (page >= fpage)
+               putchar(c);
+}
diff --git a/usr/src/cmd/rev.c b/usr/src/cmd/rev.c
new file mode 100644 (file)
index 0000000..9ced2bf
--- /dev/null
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+/* reverse lines of a file */
+
+#define N 256
+char line[N];
+FILE *input;
+
+main(argc,argv)
+char **argv;
+{
+       register i,c;
+       input = stdin;
+       do {
+               if(argc>1) {
+                       if((input=fopen(argv[1],"r"))==NULL) {
+                               fprintf(stderr,"rev: cannot open %s\n",
+                                       argv[1]);
+                               exit(1);
+                       }
+               }
+               for(;;){
+                       for(i=0;i<N;i++) {
+                               line[i] = c = getc(input);
+                               switch(c) {
+                               case EOF:
+                                       goto eof;
+                               default:
+                                       continue;
+                               case '\n':
+                                       break;
+                               }
+                               break;
+                       }
+                       while(--i>=0)
+                               putc(line[i],stdout);
+                       putc('\n',stdout);
+               }
+eof:
+               fclose(input);
+               argc--;
+               argv++;
+       } while(argc>1);
+}
diff --git a/usr/src/cmd/rm.c b/usr/src/cmd/rm.c
new file mode 100644 (file)
index 0000000..fcab28c
--- /dev/null
@@ -0,0 +1,162 @@
+int    errcode;
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+
+char   *sprintf();
+
+main(argc, argv)
+char *argv[];
+{
+       register char *arg;
+       int fflg, iflg, rflg;
+
+       fflg = 0;
+       if (isatty(0) == 0)
+               fflg++;
+       iflg = 0;
+       rflg = 0;
+       if(argc>1 && argv[1][0]=='-') {
+               arg = *++argv;
+               argc--;
+               while(*++arg != '\0')
+                       switch(*arg) {
+                       case 'f':
+                               fflg++;
+                               break;
+                       case 'i':
+                               iflg++;
+                               break;
+                       case 'r':
+                               rflg++;
+                               break;
+                       default:
+                               printf("rm: unknown option %s\n", *argv);
+                               exit(1);
+                       }
+       }
+       while(--argc > 0) {
+               if(!strcmp(*++argv, "..")) {
+                       fprintf(stderr, "rm: cannot remove `..'\n");
+                       continue;
+               }
+               rm(*argv, fflg, rflg, iflg, 0);
+       }
+
+       exit(errcode);
+}
+
+rm(arg, fflg, rflg, iflg, level)
+char arg[];
+{
+       struct stat buf;
+       struct direct direct;
+       char name[100];
+       int d;
+
+       if(stat(arg, &buf)) {
+               if (fflg==0) {
+                       printf("rm: %s nonexistent\n", arg);
+                       ++errcode;
+               }
+               return;
+       }
+       if ((buf.st_mode&S_IFMT) == S_IFDIR) {
+               if(rflg) {
+                       if (access(arg, 02) < 0) {
+                               if (fflg==0)
+                                       printf("%s not changed\n", arg);
+                               errcode++;
+                               return;
+                       }
+                       if(iflg && level!=0) {
+                               printf("directory %s: ", arg);
+                               if(!yes())
+                                       return;
+                       }
+                       if((d=open(arg, 0)) < 0) {
+                               printf("rm: %s: cannot read\n", arg);
+                               exit(1);
+                       }
+                       while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) {
+                               if(direct.d_ino != 0 && !dotname(direct.d_name)) {
+                                       sprintf(name, "%s/%.14s", arg, direct.d_name);
+                                       rm(name, fflg, rflg, iflg, level+1);
+                               }
+                       }
+                       close(d);
+                       errcode += rmdir(arg, iflg);
+                       return;
+               }
+               printf("rm: %s directory\n", arg);
+               ++errcode;
+               return;
+       }
+
+       if(iflg) {
+               printf("%s: ", arg);
+               if(!yes())
+                       return;
+       }
+       else if(!fflg) {
+               if (access(arg, 02)<0) {
+                       printf("rm: %s %o mode ", arg, buf.st_mode&0777);
+                       if(!yes())
+                               return;
+               }
+       }
+       if(unlink(arg) && (fflg==0 || iflg)) {
+               printf("rm: %s not removed\n", arg);
+               ++errcode;
+       }
+}
+
+dotname(s)
+char *s;
+{
+       if(s[0] == '.')
+               if(s[1] == '.')
+                       if(s[2] == '\0')
+                               return(1);
+                       else
+                               return(0);
+               else if(s[1] == '\0')
+                       return(1);
+       return(0);
+}
+
+rmdir(f, iflg)
+char *f;
+{
+       int status, i;
+
+       if(dotname(f))
+               return(0);
+       if(iflg) {
+               printf("%s: ", f);
+               if(!yes())
+                       return(0);
+       }
+       while((i=fork()) == -1)
+               sleep(3);
+       if(i) {
+               wait(&status);
+               return(status);
+       }
+       execl("/bin/rmdir", "rmdir", f, 0);
+       execl("/usr/bin/rmdir", "rmdir", f, 0);
+       printf("rm: can't find rmdir\n");
+       exit(1);
+}
+
+yes()
+{
+       int i, b;
+
+       i = b = getchar();
+       while(b != '\n' && b != EOF)
+               b = getchar();
+       return(i == 'y');
+}
diff --git a/usr/src/cmd/rmdir.c b/usr/src/cmd/rmdir.c
new file mode 100644 (file)
index 0000000..5b896c4
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Remove directory
+ */
+
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+int    Errors = 0;
+char   *rindex();
+char   *strcat();
+char   *strcpy();
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+       if(argc < 2) {
+               fprintf(stderr, "rmdir: arg count\n");
+               exit(1);
+       }
+       while(--argc)
+               rmdir(*++argv);
+       exit(Errors!=0);
+}
+
+rmdir(d)
+char *d;
+{
+       int     fd;
+       char    *np, name[500];
+       struct  stat    st, cst;
+       struct  direct  dir;
+
+       strcpy(name, d);
+       if((np = rindex(name, '/')) == NULL)
+               np = name;
+       if(stat(name,&st) < 0) {
+               fprintf(stderr, "rmdir: %s non-existent\n", name);
+               ++Errors;
+               return;
+       }
+       if (stat("", &cst) < 0) {
+               fprintf(stderr, "rmdir: cannot stat \"\"");
+               ++Errors;
+               exit(1);
+       }
+       if((st.st_mode & S_IFMT) != S_IFDIR) {
+               fprintf(stderr, "rmdir: %s not a directory\n", name);
+               ++Errors;
+               return;
+       }
+       if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
+               fprintf(stderr, "rmdir: cannot remove current directory\n");
+               ++Errors;
+               return;
+       }
+       if((fd = open(name,0)) < 0) {
+               fprintf(stderr, "rmdir: %s unreadable\n", name);
+               ++Errors;
+               return;
+       }
+       while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) {
+               if(dir.d_ino == 0) continue;
+               if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."))
+                       continue;
+               fprintf(stderr, "rmdir: %s not empty\n", name);
+               ++Errors;
+               close(fd);
+               return;
+       }
+       close(fd);
+       if(!strcmp(np, ".") || !strcmp(np, "..")) {
+               fprintf(stderr, "rmdir: cannot remove . or ..\n");
+               ++Errors;
+               return;
+       }
+       strcat(name, "/.");
+       if((access(name, 0)) < 0) {             /* name/. non-existent */
+               strcat(name, ".");
+               goto unl;
+       }
+       strcat(name, ".");
+       if((access(name, 0)) < 0)               /* name/.. non-existent */
+               goto unl2;
+       if(access(name, 02)) {
+               name[strlen(name)-3] = '\0';
+               fprintf(stderr, "rmdir: %s: no permission\n", name);
+               ++Errors;
+               return;
+       }
+unl:
+       unlink(name);   /* unlink name/.. */
+unl2:
+       name[strlen(name)-1] = '\0';
+       unlink(name);   /* unlink name/.  */
+       name[strlen(name)-2] = '\0';
+       if (unlink(name) < 0) {
+               fprintf(stderr, "rmdir: %s not removed\n", name);
+               ++Errors;
+       }
+}
diff --git a/usr/src/cmd/sleep.c b/usr/src/cmd/sleep.c
new file mode 100644 (file)
index 0000000..a52bc3d
--- /dev/null
@@ -0,0 +1,21 @@
+main(argc, argv)
+char **argv;
+{
+       int c, n;
+       char *s;
+
+       n = 0;
+       if(argc < 2) {
+               printf("arg count\n");
+               exit(0);
+       }
+       s = argv[1];
+       while(c = *s++) {
+               if(c<'0' || c>'9') {
+                       printf("bad character\n");
+                       exit(0);
+               }
+               n = n*10 + c - '0';
+       }
+       sleep(n);
+}
diff --git a/usr/src/cmd/sort.c b/usr/src/cmd/sort.c
new file mode 100644 (file)
index 0000000..bccb330
--- /dev/null
@@ -0,0 +1,902 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define        L       512
+#define        N       7
+#define        C       20
+#define        MEM     (16*2048)
+#define NF     10
+
+FILE   *is, *os;
+char   *dirtry[] = {"/usr/tmp", "/tmp", NULL};
+char   **dirs;
+char   file1[30];
+char   *file = file1;
+char   *filep;
+int    nfiles;
+unsigned       nlines;
+unsigned       ntext;
+int    *lspace;
+char   *tspace;
+int    cmp(), cmpa();
+int    (*compare)() = cmpa;
+char   *eol();
+int    term();
+int    mflg;
+int    cflg;
+int    uflg;
+char   *outfil;
+int unsafeout; /*kludge to assure -m -o works*/
+char   tabchar;
+int    eargc;
+char   **eargv;
+
+char zero[256];
+
+char   fold[256] = {
+       0200,0201,0202,0203,0204,0205,0206,0207,
+       0210,0211,0212,0213,0214,0215,0216,0217,
+       0220,0221,0222,0223,0224,0225,0226,0227,
+       0230,0231,0232,0233,0234,0235,0236,0237,
+       0240,0241,0242,0243,0244,0245,0246,0247,
+       0250,0251,0252,0253,0254,0255,0256,0257,
+       0260,0261,0262,0263,0264,0265,0266,0267,
+       0270,0271,0272,0273,0274,0275,0276,0277,
+       0300,0301,0302,0303,0304,0305,0306,0307,
+       0310,0311,0312,0313,0314,0315,0316,0317,
+       0320,0321,0322,0323,0324,0325,0326,0327,
+       0330,0331,0332,0333,0334,0335,0336,0337,
+       0340,0341,0342,0343,0344,0345,0346,0347,
+       0350,0351,0352,0353,0354,0355,0356,0357,
+       0360,0361,0362,0363,0364,0365,0366,0367,
+       0370,0371,0372,0373,0374,0375,0376,0377,
+       0000,0001,0002,0003,0004,0005,0006,0007,
+       0010,0011,0012,0013,0014,0015,0016,0017,
+       0020,0021,0022,0023,0024,0025,0026,0027,
+       0030,0031,0032,0033,0034,0035,0036,0037,
+       0040,0041,0042,0043,0044,0045,0046,0047,
+       0050,0051,0052,0053,0054,0055,0056,0057,
+       0060,0061,0062,0063,0064,0065,0066,0067,
+       0070,0071,0072,0073,0074,0075,0076,0077,
+       0100,0101,0102,0103,0104,0105,0106,0107,
+       0110,0111,0112,0113,0114,0115,0116,0117,
+       0120,0121,0122,0123,0124,0125,0126,0127,
+       0130,0131,0132,0133,0134,0134,0136,0137,
+       0140,0101,0102,0103,0104,0105,0106,0107,
+       0110,0111,0112,0113,0114,0115,0116,0117,
+       0120,0121,0122,0123,0124,0125,0126,0127,
+       0130,0131,0132,0173,0174,0175,0176,0177
+};
+char nofold[256] = {
+       0200,0201,0202,0203,0204,0205,0206,0207,
+       0210,0211,0212,0213,0214,0215,0216,0217,
+       0220,0221,0222,0223,0224,0225,0226,0227,
+       0230,0231,0232,0233,0234,0235,0236,0237,
+       0240,0241,0242,0243,0244,0245,0246,0247,
+       0250,0251,0252,0253,0254,0255,0256,0257,
+       0260,0261,0262,0263,0264,0265,0266,0267,
+       0270,0271,0272,0273,0274,0275,0276,0277,
+       0300,0301,0302,0303,0304,0305,0306,0307,
+       0310,0311,0312,0313,0314,0315,0316,0317,
+       0320,0321,0322,0323,0324,0325,0326,0327,
+       0330,0331,0332,0333,0334,0335,0336,0337,
+       0340,0341,0342,0343,0344,0345,0346,0347,
+       0350,0351,0352,0353,0354,0355,0356,0357,
+       0360,0361,0362,0363,0364,0365,0366,0367,
+       0370,0371,0372,0373,0374,0375,0376,0377,
+       0000,0001,0002,0003,0004,0005,0006,0007,
+       0010,0011,0012,0013,0014,0015,0016,0017,
+       0020,0021,0022,0023,0024,0025,0026,0027,
+       0030,0031,0032,0033,0034,0035,0036,0037,
+       0040,0041,0042,0043,0044,0045,0046,0047,
+       0050,0051,0052,0053,0054,0055,0056,0057,
+       0060,0061,0062,0063,0064,0065,0066,0067,
+       0070,0071,0072,0073,0074,0075,0076,0077,
+       0100,0101,0102,0103,0104,0105,0106,0107,
+       0110,0111,0112,0113,0114,0115,0116,0117,
+       0120,0121,0122,0123,0124,0125,0126,0127,
+       0130,0131,0132,0133,0134,0135,0136,0137,
+       0140,0141,0142,0143,0144,0145,0146,0147,
+       0150,0151,0152,0153,0154,0155,0156,0157,
+       0160,0161,0162,0163,0164,0165,0166,0167,
+       0170,0171,0172,0173,0174,0175,0176,0177
+};
+
+char   nonprint[256] = {
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
+};
+
+char   dict[256] = {
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+       0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
+       1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
+       1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+       0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
+};
+
+struct field {
+       char *code;
+       char *ignore;
+       int nflg;
+       int rflg;
+       int bflg[2];
+       int m[2];
+       int n[2];
+}      fields[NF];
+struct field proto = {
+       nofold+128,
+       zero+128,
+       0,
+       1,
+       0,0,
+       0,-1,
+       0,0
+};
+int    nfields;
+int    error = 1;
+char   *setfil();
+char   *sbrk();
+char   *brk();
+
+main(argc, argv)
+char **argv;
+{
+       register a;
+       extern char end[1];
+       char *ep;
+       char *arg;
+       struct field *p, *q;
+       int i;
+       unsigned pid;
+
+       copyproto();
+       eargv = argv;
+       while (--argc > 0) {
+               if(**++argv == '-') for(arg = *argv;;) {
+                       switch(*++arg) {
+                       case '\0':
+                               if(arg[-1] == '-')
+                                       eargv[eargc++] = "-";
+                               break;
+
+                       case 'o':
+                               if(--argc > 0)
+                                       outfil = *++argv;
+                               continue;
+
+                       case 'T':
+                               if (--argc > 0)
+                                       dirtry[0] = *++argv;
+                               continue;
+
+                       default:
+                               field(++*argv,nfields>0);
+                               break;
+                       }
+                       break;
+               } else if (**argv == '+') {
+                       if(++nfields>=NF) {
+                               diag("too many keys","");
+                               exit(1);
+                       }
+                       copyproto();
+                       field(++*argv,0);
+               } else
+                       eargv[eargc++] = *argv;
+       }
+       q = &fields[0];
+       for(a=1; a<=nfields; a++) {
+               p = &fields[a];
+               if(p->code != proto.code) continue;
+               if(p->ignore != proto.ignore) continue;
+               if(p->nflg != proto.nflg) continue;
+               if(p->rflg != proto.rflg) continue;
+               if(p->bflg[0] != proto.bflg[0]) continue;
+               if(p->bflg[1] != proto.bflg[1]) continue;
+               p->code = q->code;
+               p->ignore = q->ignore;
+               p->nflg = q->nflg;
+               p->rflg = q->rflg;
+               p->bflg[0] = p->bflg[1] = q->bflg[0];
+       }
+       if(eargc == 0)
+               eargv[eargc++] = "-";
+       if(cflg && eargc>1) {
+               diag("can check only 1 file","");
+               exit(1);
+       }
+       safeoutfil();
+
+       ep = end + MEM;
+       lspace = (int *)sbrk(0);
+       while((int)brk(ep) == -1)
+               ep -= 512;
+       brk(ep -= 512); /* for recursion */
+       a = ep - (char*)lspace;
+       nlines = (a-L);
+       nlines /= (5*(sizeof(char *)/sizeof(char)));
+       ntext = nlines*8;
+       tspace = (char *)(lspace + nlines);
+       a = -1;
+       for(dirs=dirtry; *dirs; dirs++) {
+               sprintf(filep=file1, "%s/stm%05uaa", *dirs, getpid());
+               while (*filep)
+                       filep++;
+               filep -= 2;
+               if ( (a=creat(file, 0600)) >=0)
+                       break;
+       }
+       if(a < 0) {
+               diag("can't locate temp","");
+               exit(1);
+       }
+       close(a);
+       signal(SIGHUP, term);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, term);
+       signal(SIGPIPE,term);
+       signal(SIGTERM,term);
+       nfiles = eargc;
+       if(!mflg && !cflg) {
+               sort();
+               fclose(stdin);
+       }
+       for(a = mflg|cflg?0:eargc; a+N<nfiles || unsafeout&&a<eargc; a=i) {
+               i = a+N;
+               if(i>=nfiles)
+                       i = nfiles;
+               newfile();
+               merge(a, i);
+       }
+       if(a != nfiles) {
+               oldfile();
+               merge(a, nfiles);
+       }
+       error = 0;
+       term();
+}
+
+sort()
+{
+       register char *cp;
+       register char **lp;
+       register c;
+       int done;
+       int i;
+       char *f;
+
+       done = 0;
+       i = 0;
+       c = EOF;
+       do {
+               cp = tspace;
+               lp = (char **)lspace;
+               while(lp < (char **)lspace+nlines && cp < tspace+ntext) {
+                       *lp++ = cp;
+                       while(c != '\n') {
+                               if(c != EOF) {
+                                       *cp++ = c;
+                                       c = getc(is);
+                                       continue;
+                               } else if(is)
+                                       fclose(is);
+                               if(i < eargc) {
+                                       if((f = setfil(i++)) == 0)
+                                               is = stdin;
+                                       else if((is = fopen(f, "r")) == NULL)
+                                               cant(f);
+                                       c = getc(is);
+                               } else
+                                       break;
+                       }
+                       *cp++ = '\n';
+                       if(c == EOF) {
+                               done++;
+                               lp--;
+                               break;
+                       }
+                       c = getc(is);
+               }
+               qsort((char **)lspace, lp);
+               if(done == 0 || nfiles != eargc)
+                       newfile();
+               else
+                       oldfile();
+               while(lp > (char **)lspace) {
+                       cp = *--lp;
+                       if(*cp)
+                               do
+                               putc(*cp, os);
+                               while(*cp++ != '\n');
+               }
+               fclose(os);
+       } while(done == 0);
+}
+
+struct merg
+{
+       char    l[L];
+       FILE    *b;
+} *ibuf[256];
+
+merge(a,b)
+{
+       struct  merg    *p;
+       register char   *cp, *dp;
+       register        i;
+       struct merg **ip, *jp;
+       char    *f;
+       int     j;
+       int     k, l;
+       int     muflg;
+
+       p = (struct merg *)lspace;
+       j = 0;
+       for(i=a; i < b; i++) {
+               f = setfil(i);
+               if(f == 0)
+                       p->b = stdin;
+               else if((p->b = fopen(f, "r")) == NULL)
+                       cant(f);
+               ibuf[j] = p;
+               if(!rline(p))   j++;
+               p++;
+       }
+
+       do {
+               i = j;
+               qsort((char **)ibuf, (char **)(ibuf+i));
+               l = 0;
+               while(i--) {
+                       cp = ibuf[i]->l;
+                       if(*cp == '\0') {
+                               l = 1;
+                               if(rline(ibuf[i])) {
+                                       k = i;
+                                       while(++k < j)
+                                               ibuf[k-1] = ibuf[k];
+                                       j--;
+                               }
+                       }
+               }
+       } while(l);
+
+       muflg = mflg & uflg | cflg;
+       i = j;
+       while(i > 0) {
+               cp = ibuf[i-1]->l;
+               if(!cflg && (uflg == 0 || muflg ||
+                       (*compare)(ibuf[i-1]->l,ibuf[i-2]->l)))
+                       do
+                               putc(*cp, os);
+                       while(*cp++ != '\n');
+               if(muflg){
+                       cp = ibuf[i-1]->l;
+                       dp = p->l;
+                       do {
+                       } while((*dp++ = *cp++) != '\n');
+               }
+               for(;;) {
+                       if(rline(ibuf[i-1])) {
+                               i--;
+                               if(i == 0)
+                                       break;
+                               if(i == 1)
+                                       muflg = uflg;
+                       }
+                       ip = &ibuf[i];
+                       while(--ip>ibuf&&(*compare)(ip[0]->l,ip[-1]->l)<0){
+                               jp = *ip;
+                               *ip = *(ip-1);
+                               *(ip-1) = jp;
+                       }
+                       if(!muflg)
+                               break;
+                       j = (*compare)(ibuf[i-1]->l,p->l);
+                       if(cflg) {
+                               if(j > 0)
+                                       disorder("disorder:",ibuf[i-1]->l);
+                               else if(uflg && j==0)
+                                       disorder("nonunique:",ibuf[i-1]->l);
+                       } else if(j == 0)
+                               continue;
+                       break;
+               }
+       }
+       p = (struct merg *)lspace;
+       for(i=a; i<b; i++) {
+               fclose(p->b);
+               p++;
+               if(i >= eargc)
+                       unlink(setfil(i));
+       }
+       fclose(os);
+}
+
+rline(mp)
+struct merg *mp;
+{
+       register char *cp;
+       register char *ce;
+       FILE *bp;
+       register c;
+
+       bp = mp->b;
+       cp = mp->l;
+       ce = cp+L;
+       do {
+               c = getc(bp);
+               if(c == EOF)
+                       return(1);
+               if(cp>=ce)
+                       cp--;
+               *cp++ = c;
+       } while(c!='\n');
+       return(0);
+}
+
+disorder(s,t)
+char *s, *t;
+{
+       register char *u;
+       for(u=t; *u!='\n';u++) ;
+       *u = 0;
+       diag(s,t);
+       term();
+}
+
+newfile()
+{
+       register char *f;
+
+       f = setfil(nfiles);
+       if((os=fopen(f, "w")) == NULL) {
+               diag("can't create ",f);
+               term();
+       }
+       nfiles++;
+}
+
+char *
+setfil(i)
+{
+
+       if(i < eargc)
+               if(eargv[i][0] == '-' && eargv[i][1] == '\0')
+                       return(0);
+               else
+                       return(eargv[i]);
+       i -= eargc;
+       filep[0] = i/26 + 'a';
+       filep[1] = i%26 + 'a';
+       return(file);
+}
+
+oldfile()
+{
+
+       if(outfil) {
+               if((os=fopen(outfil, "w")) == NULL) {
+                       diag("can't create ",outfil);
+                       term();
+               }
+       } else
+               os = stdout;
+}
+
+safeoutfil()
+{
+       register int i;
+       struct stat obuf,ibuf;
+
+       if(!mflg||outfil==0)
+               return;
+       if(stat(outfil,&obuf)==-1)
+               return;
+       for(i=eargc-N;i<eargc;i++) {    /*-N is suff., not nec.*/
+               if(stat(eargv[i],&ibuf)==-1)
+                       continue;
+               if(obuf.st_dev==ibuf.st_dev&&
+                  obuf.st_ino==ibuf.st_ino)
+                       unsafeout++;
+       }
+}
+
+cant(f)
+char *f;
+{
+
+       diag("can't open ",f);
+       term();
+}
+
+diag(s,t)
+char *s, *t;
+{
+       fputs("sort: ",stderr);
+       fputs(s,stderr);
+       fputs(t,stderr);
+       fputs("\n",stderr);
+}
+
+term()
+{
+       register i;
+
+       signal(SIGINT, SIG_IGN);
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGTERM, SIG_IGN);
+       if(nfiles == eargc)
+               nfiles++;
+       for(i=eargc; i<=nfiles; i++) {  /*<= in case of interrupt*/
+               unlink(setfil(i));      /*with nfiles not updated*/
+       }
+       exit(error);
+}
+
+cmp(i, j)
+char *i, *j;
+{
+       register char *pa, *pb;
+       char *skip();
+       char *code, *ignore;
+       int a, b;
+       int k;
+       char *la, *lb;
+       register int sa;
+       int sb;
+       char *ipa, *ipb, *jpa, *jpb;
+       struct field *fp;
+
+       for(k = nfields>0; k<=nfields; k++) {
+               fp = &fields[k];
+               pa = i;
+               pb = j;
+               if(k) {
+                       la = skip(pa, fp, 1);
+                       pa = skip(pa, fp, 0);
+                       lb = skip(pb, fp, 1);
+                       pb = skip(pb, fp, 0);
+               } else {
+                       la = eol(pa);
+                       lb = eol(pb);
+               }
+               if(fp->nflg) {
+                       while(blank(*pa))
+                               pa++;
+                       while(blank(*pb))
+                               pb++;
+                       sa = sb = fp->rflg;
+                       if(*pa == '-') {
+                               pa++;
+                               sa = -sa;
+                       }
+                       if(*pb == '-') {
+                               pb++;
+                               sb = -sb;
+                       }
+                       for(ipa = pa; ipa<la&&isdigit(*ipa); ipa++) ;
+                       for(ipb = pb; ipb<lb&&isdigit(*ipb); ipb++) ;
+                       jpa = ipa;
+                       jpb = ipb;
+                       a = 0;
+                       if(sa==sb)
+                               while(ipa > pa && ipb > pb)
+                                       if(b = *--ipb - *--ipa)
+                                               a = b;
+                       while(ipa > pa)
+                               if(*--ipa != '0')
+                                       return(-sa);
+                       while(ipb > pb)
+                               if(*--ipb != '0')
+                                       return(sb);
+                       if(a) return(a*sa);
+                       if(*(pa=jpa) == '.')
+                               pa++;
+                       if(*(pb=jpb) == '.')
+                               pb++;
+                       if(sa==sb)
+                               while(pa<la && isdigit(*pa)
+                                  && pb<lb && isdigit(*pb))
+                                       if(a = *pb++ - *pa++)
+                                               return(a*sa);
+                       while(pa<la && isdigit(*pa))
+                               if(*pa++ != '0')
+                                       return(-sa);
+                       while(pb<lb && isdigit(*pb))
+                               if(*pb++ != '0')
+                                       return(sb);
+                       continue;
+               }
+               code = fp->code;
+               ignore = fp->ignore;
+loop: 
+               while(ignore[*pa])
+                       pa++;
+               while(ignore[*pb])
+                       pb++;
+               if(pa>=la || *pa=='\n')
+                       if(pb<lb && *pb!='\n')
+                               return(fp->rflg);
+                       else continue;
+               if(pb>=lb || *pb=='\n')
+                       return(-fp->rflg);
+               if((sa = code[*pb++]-code[*pa++]) == 0)
+                       goto loop;
+               return(sa*fp->rflg);
+       }
+       if(uflg)
+               return(0);
+       return(cmpa(i, j));
+}
+
+cmpa(pa, pb)
+register char *pa, *pb;
+{
+       while(*pa == *pb) {
+               if(*pa++ == '\n')
+                       return(0);
+               pb++;
+       }
+       return(
+               *pa == '\n' ? fields[0].rflg:
+               *pb == '\n' ?-fields[0].rflg:
+               *pb > *pa   ? fields[0].rflg:
+               -fields[0].rflg
+       );
+}
+
+char *
+skip(pp, fp, j)
+struct field *fp;
+char *pp;
+{
+       register i;
+       register char *p;
+
+       p = pp;
+       if( (i=fp->m[j]) < 0)
+               return(eol(p));
+       while(i-- > 0) {
+               if(tabchar != 0) {
+                       while(*p != tabchar)
+                               if(*p != '\n')
+                                       p++;
+                               else goto ret;
+                       p++;
+               } else {
+                       while(blank(*p))
+                               p++;
+                       while(!blank(*p))
+                               if(*p != '\n')
+                                       p++;
+                               else goto ret;
+               }
+       }
+       if(fp->bflg[j])
+               while(blank(*p))
+                       p++;
+       i = fp->n[j];
+       while(i-- > 0) {
+               if(*p != '\n')
+                       p++;
+               else goto ret;
+       } 
+ret:
+       return(p);
+}
+
+char *
+eol(p)
+register char *p;
+{
+       while(*p != '\n') p++;
+       return(p);
+}
+
+copyproto()
+{
+       register i;
+       register int *p, *q;
+
+       p = (int *)&proto;
+       q = (int *)&fields[nfields];
+       for(i=0; i<sizeof(proto)/sizeof(*p); i++)
+               *q++ = *p++;
+}
+
+field(s,k)
+char *s;
+{
+       register struct field *p;
+       register d;
+       p = &fields[nfields];
+       d = 0;
+       for(; *s!=0; s++) {
+               switch(*s) {
+               case '\0':
+                       return;
+
+               case 'b':
+                       p->bflg[k]++;
+                       break;
+
+               case 'd':
+                       p->ignore = dict+128;
+                       break;
+
+               case 'f':
+                       p->code = fold+128;
+                       break;
+               case 'i':
+                       p->ignore = nonprint+128;
+                       break;
+
+               case 'c':
+                       cflg = 1;
+                       continue;
+
+               case 'm':
+                       mflg = 1;
+                       continue;
+
+               case 'n':
+                       p->nflg++;
+                       break;
+               case 't':
+                       tabchar = *++s;
+                       if(tabchar == 0) s--;
+                       continue;
+
+               case 'r':
+                       p->rflg = -1;
+                       continue;
+               case 'u':
+                       uflg = 1;
+                       break;
+
+               case '.':
+                       if(p->m[k] == -1)       /* -m.n with m missing */
+                               p->m[k] = 0;
+                       d = &fields[0].n[0]-&fields[0].m[0];
+
+               default:
+                       p->m[k+d] = number(&s);
+               }
+               compare = cmp;
+       }
+}
+
+number(ppa)
+char **ppa;
+{
+       int n;
+       register char *pa;
+       pa = *ppa;
+       n = 0;
+       while(isdigit(*pa)) {
+               n = n*10 + *pa - '0';
+               *ppa = pa++;
+       }
+       return(n);
+}
+
+blank(c)
+{
+       if(c==' ' || c=='\t')
+               return(1);
+       return(0);
+}
+
+#define qsexc(p,q) t= *p;*p= *q;*q=t
+#define qstexc(p,q,r) t= *p;*p= *r;*r= *q;*q=t
+
+qsort(a,l)
+char **a, **l;
+{
+       register char **i, **j;
+       char **k;
+       char **lp, **hp;
+       int c;
+       char *t;
+       unsigned n;
+
+
+
+start:
+       if((n=l-a) <= 1)
+               return;
+
+
+       n /= 2;
+       hp = lp = a+n;
+       i = a;
+       j = l-1;
+
+
+       for(;;) {
+               if(i < lp) {
+                       if((c = (*compare)(*i, *lp)) == 0) {
+                               --lp;
+                               qsexc(i, lp);
+                               continue;
+                       }
+                       if(c < 0) {
+                               ++i;
+                               continue;
+                       }
+               }
+
+loop:
+               if(j > hp) {
+                       if((c = (*compare)(*hp, *j)) == 0) {
+                               ++hp;
+                               qsexc(hp, j);
+                               goto loop;
+                       }
+                       if(c > 0) {
+                               if(i == lp) {
+                                       ++hp;
+                                       qstexc(i, hp, j);
+                                       i = ++lp;
+                                       goto loop;
+                               }
+                               qsexc(i, j);
+                               --j;
+                               ++i;
+                               continue;
+                       }
+                       --j;
+                       goto loop;
+               }
+
+
+               if(i == lp) {
+                       if(uflg)
+                               for(k=lp+1; k<=hp;) **k++ = '\0';
+                       if(lp-a >= l-hp) {
+                               qsort(hp+1, l);
+                               l = lp;
+                       } else {
+                               qsort(a, lp);
+                               a = hp+1;
+                       }
+                       goto start;
+               }
+
+
+               --lp;
+               qstexc(j, lp, i);
+               j = --hp;
+       }
+}
+
diff --git a/usr/src/cmd/spline.c b/usr/src/cmd/spline.c
new file mode 100644 (file)
index 0000000..00b453d
--- /dev/null
@@ -0,0 +1,333 @@
+#include <stdio.h>
+
+#define NP 1000
+#define INF 1.e37
+
+struct proj { int lbf,ubf; float a,b,lb,ub,quant,mult,val[NP]; } x,y;
+float *diag, *r;
+float dx = 1.;
+float ni = 100.;
+int n;
+int auta;
+int periodic;
+float konst = 0.0;
+float zero = 0.;
+
+/* Spline fit technique
+let x,y be vectors of abscissas and ordinates
+    h   be vector of differences h\e9i\e8=x\e9i\e8-x\e9i-1\e\e9\e8\e8
+    y"  be vector of 2nd derivs of approx function
+If the points are numbered 0,1,2,...,n+1 then y" satisfies
+(R W Hamming, Numerical Methods for Engineers and Scientists,
+2nd Ed, p349ff)
+       h\e9i\e8y"\b\e9i-1\e9\e8\e8+2(h\e9i\e8+h\e9i+1\e8)y"\b\e9i\e8+h\e9i+1\e8y"\b\e9i+1\e8
+       
+       = 6[(y\e9i+1\e8-y\e9i\e8)/h\e9i+1\e8-(y\e9i\e8-y\e9i-1\e8)/h\e9i\e8]   i=1,2,...,n
+
+where y"\b\e90\e8 = y"\b\e9n+1\e8 = 0
+This is a symmetric tridiagonal system of the form
+
+       | a\e91\e8 h\e92\e8               |  |y"\b\e91\e8|      |b\e91\e8|
+       | h\e92\e8 a\e92\e8 h\e93\e8            |  |y"\b\e92\e8|      |b\e92\e8|
+       |    h\e93\e8 a\e93\e8 h\e94\e8         |  |y"\b\e93\e8|  =   |b\e93\e8|
+       |         .           |  | .|      | .|
+       |            .        |  | .|      | .|
+It can be triangularized into
+       | d\e91\e8 h\e92\e8               |  |y"\b\e91\e8|      |r\e91\e8|
+       |    d\e92\e8 h\e93\e8            |  |y"\b\e92\e8|      |r\e92\e8|
+       |       d\e93\e8 h\e94\e8         |  |y"\b\e93\e8|  =   |r\e93\e8|
+       |          .          |  | .|      | .|
+       |             .       |  | .|      | .|
+where
+       d\e91\e8 = a\e91\e8
+
+       r\e90\e8 = 0
+
+       d\e9i\e8 = a\e9i\e8 - h\e9i\e8\b\e82\e9/d\e9i-1\e8 1<i<\b_n
+
+       r\e9i\e8 = b\e9i\e8 - h\e9i\e8r\e9i-1\e8/d\e9i-1\ei\e8     1<\b_i<\b_n
+
+the back solution is
+       y"\b\e9n\e8 = r\e9n\e8/d\e9n\e8
+
+       y"\b\e9i\e8 = (r\e9i\e8-h\e9i+1\e8y"\b\e9i+1\e8)/d\e9i\e8   1<\b_i<n
+
+superficially, d\e9i\e8 and r\e9i\e8 don't have to be stored for they can be
+recalculated backward by the formulas
+
+       d\e9i-1\e8 = h\e9i\e8\b\e82\e9/(a\e9i\e8-d\e9i\e8) 1<i<\b_n
+
+       r\e9i-1\e8 = (b\e9i\e8-r\e9i\e8)d\e9i-1\e8/h\e9i\e8       1<i<\b_n
+
+unhappily it turns out that the recursion forward for d
+is quite strongly geometrically convergent--and is wildly
+unstable going backward.
+There's similar trouble with r, so the intermediate
+results must be kept.
+
+Note that n-1 in the program below plays the role of n+1 in the theory
+
+Other boundary conditions\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b_________________________
+
+The boundary conditions are easily generalized to handle
+
+       y\e90\e8\b" = ky\e91\e8\b", y\e9n+1\e8\b\b\b"   = ky\e9n\e8\b"
+
+for some constant k.  The above analysis was for k = 0;
+k = 1 fits parabolas perfectly as well as stright lines;
+k = 1/2 has been recommended as somehow pleasant.
+
+All that is necessary is to add h\e91\e8 to a\e91\e8 and h\e9n+1\e8 to a\e9n\e8.
+
+
+Periodic case\b\b\b\b\b\b\b\b\b\b\b\b\b_____________
+
+To do this, add 1 more row and column thus
+
+       | a\e91\e8 h\e92\e8            h\e91\e8 |  |y\e91\e8\b"|     |b\e91\e8|
+       | h\e92\e8 a\e92\e8 h\e93\e8            |  |y\e92\e8\b"|     |b\e92\e8|
+       |    h\e93\e8 a\e94\e8 h\e94\e8         |  |y\e93\e8\b"|     |b\e93\e8|
+       |                     |  | .|  =  | .|
+       |             .       |  | .|     | .|
+       | h\e91\e8            h\e90\e8 a\e90\e8 |  | .|     | .|
+
+where h\e90\e8=\b_ h\e9n+1\e8
+
+The same diagonalization procedure works, except for
+the effect of the 2 corner elements.  Let s\e9i\e8 be the part
+of the last element in the i\e8th\e9 "diagonalized" row that
+arises from the extra top corner element.
+
+               s\e91\e8 = h\e91\e8
+
+               s\e9i\e8 = -s\e9i-1\e8h\e9i\e8/d\e9i-1\e8       2<\b_i<\b_n+1
+
+After "diagonalizing", the lower corner element remains.
+Call t\e9i\e8 the bottom element that appears in the i\e8th\e9 colomn
+as the bottom element to its left is eliminated
+
+               t\e91\e8 = h\e91\e8
+
+               t\e9i\e8 = -t\e9i-1\e8h\e9i\e8/d\e9i-1\e8
+
+Evidently t\e9i\e8 = s\e9i\e8.
+Elimination along the bottom row
+introduces further corrections to the bottom right element
+and to the last element of the right hand side.
+Call these corrections u and v.
+
+       u\e91\e8 = v\e91\e8 = 0
+
+       u\e9i\e8 = u\e9i-1\e8-s\e9i-1\e8*t\e9i-1\e8/d\e9i-1\e8
+
+       v\e9i\e8 = v\e9i-1\e8-r\e9i-1\e8*t\e9i-1\e8/d\e9i-1\e8    2<\b_i<\b_n+1
+
+The back solution is now obtained as follows
+
+       y"\b\e9n+1\e8 = (r\e9n+1\e8+v\e9n+1\e8)/(d\e9n+1\e8+s\e9n+1\e8+t\e9n+1\e8+u\e9n+1\e8)
+
+       y"\b\e9i\e8 = (r\e9i\e8-h\e9i+1\e8*y\e9i+1\e8-s\e9i\e8*y\e9n+1\e8)/d\e9i\e8    1<\b_i<\b_n
+
+Interpolation in the interval x\e9i\e8<\b_x<\b_x\e9i+1\e8 is by the formula
+
+       y = y\e9i\e8x\e9+\e8 + y\e9i+1\e8x\e9-\e8 -(h\e82\e9\b\e9i+1\e8/6)[y"\b\e9i\e8(x\e9+\e8-x\e9+\e8\e8\b3\e9)+y"\b\e9i+1\e8(x\e9-\e8-x\e9-\e8\b\e83\e9)]
+where
+       x\e9+\e8 = x\e9i+1\e8-x
+
+       x\e9-\e8 = x-x\e9i\e8
+*/
+
+float
+rhs(i){
+       int i_;
+       double zz;
+       i_ = i==n-1?0:i;
+       zz = (y.val[i]-y.val[i-1])/(x.val[i]-x.val[i-1]);
+       return(6*((y.val[i_+1]-y.val[i_])/(x.val[i+1]-x.val[i]) - zz));
+}
+
+spline(){
+       float d,s,u,v,hi,hi1;
+       float h;
+       float D2yi,D2yi1,D2yn1,x0,x1,yy,a;
+       int end;
+       float corr;
+       int i,j,m;
+       if(n<3) return(0);
+       if(periodic) konst = 0;
+       d = 1;
+       r[0] = 0;
+       s = periodic?-1:0;
+       for(i=0;++i<n-!periodic;){      /* triangularize */
+               hi = x.val[i]-x.val[i-1];
+               hi1 = i==n-1?x.val[1]-x.val[0]:
+                       x.val[i+1]-x.val[i];
+               if(hi1*hi<=0) return(0);
+               u = i==1?zero:u-s*s/d;
+               v = i==1?zero:v-s*r[i-1]/d;
+               r[i] = rhs(i)-hi*r[i-1]/d;
+               s = -hi*s/d;
+               a = 2*(hi+hi1);
+               if(i==1) a += konst*hi;
+               if(i==n-2) a += konst*hi1;
+               diag[i] = d = i==1? a:
+                   a - hi*hi/d; 
+               }
+       D2yi = D2yn1 = 0;
+       for(i=n-!periodic;--i>=0;){     /* back substitute */
+               end = i==n-1;
+               hi1 = end?x.val[1]-x.val[0]:
+                       x.val[i+1]-x.val[i];
+               D2yi1 = D2yi;
+               if(i>0){
+                       hi = x.val[i]-x.val[i-1];
+                       corr = end?2*s+u:zero;
+                       D2yi = (end*v+r[i]-hi1*D2yi1-s*D2yn1)/
+                               (diag[i]+corr);
+                       if(end) D2yn1 = D2yi;
+                       if(i>1){
+                               a = 2*(hi+hi1);
+                               if(i==1) a += konst*hi;
+                               if(i==n-2) a += konst*hi1;
+                               d = diag[i-1];
+                               s = -s*d/hi; 
+                       }}
+               else D2yi = D2yn1;
+               if(!periodic) {
+                       if(i==0) D2yi = konst*D2yi1;
+                       if(i==n-2) D2yi1 = konst*D2yi;
+                       }
+               if(end) continue;
+               m = hi1>0?ni:-ni;
+               m = 1.001*m*hi1/(x.ub-x.lb);
+               if(m<=0) m = 1;
+               h = hi1/m;
+               for(j=m;j>0||i==0&&j==0;j--){   /* interpolate */
+                       x0 = (m-j)*h/hi1;
+                       x1 = j*h/hi1;
+                       yy = D2yi*(x0-x0*x0*x0)+D2yi1*(x1-x1*x1*x1);
+                       yy = y.val[i]*x0+y.val[i+1]*x1 -hi1*hi1*yy/6;
+                       printf("%f ",x.val[i]+j*h);
+                       printf("%f\n",yy);
+                       }
+               }
+       return(1);
+       }
+readin() {
+       for(n=0;n<NP;n++){
+               if(auta) x.val[n] = n*dx+x.lb;
+               else if(!getfloat(&x.val[n])) break;
+               if(!getfloat(&y.val[n])) break; } }
+
+getfloat(p)
+       float *p;{
+       char buf[30];
+       register c;
+       int i;
+       extern double atof();
+       for(;;){
+               c = getchar();
+               if (c==EOF) {
+                       *buf = '\0';
+                       return(0);
+               }
+               *buf = c;
+               switch(*buf){
+                       case ' ':
+                       case '\t':
+                       case '\n':
+                               continue;}
+               break;}
+       for(i=1;i<30;i++){
+               c = getchar();
+               if (c==EOF) {
+                       buf[i] = '\0';
+                       break;
+               }
+               buf[i] = c;
+               if('0'<=c && c<='9') continue;
+               switch(c) {
+                       case '.':
+                       case '+':
+                       case '-':
+                       case 'E':
+                       case 'e':
+                               continue;}
+               break; }
+       buf[i] = ' ';
+       *p = atof(buf);
+       return(1); }
+
+getlim(p)
+       struct proj *p; {
+       int i;
+       for(i=0;i<n;i++) {
+               if(!p->lbf && p->lb>(p->val[i])) p->lb = p->val[i];
+               if(!p->ubf && p->ub<(p->val[i])) p->ub = p->val[i]; }
+       }
+
+
+main(argc,argv)
+       char *argv[];{
+       extern char *malloc();
+       int i;
+       x.lbf = x.ubf = y.lbf = y.ubf = 0;
+       x.lb = INF;
+       x.ub = -INF;
+       y.lb = INF;
+       y.ub = -INF;
+       while(--argc > 0) {
+               argv++;
+again:         switch(argv[0][0]) {
+               case '-':
+                       argv[0]++;
+                       goto again;
+               case 'a':
+                       auta = 1;
+                       numb(&dx,&argc,&argv);
+                       break;
+               case 'k':
+                       numb(&konst,&argc,&argv);
+                       break;
+               case 'n':
+                       numb(&ni,&argc,&argv);
+                       break;
+               case 'p':
+                       periodic = 1;
+                       break;
+               case 'x':
+                       if(!numb(&x.lb,&argc,&argv)) break;
+                       x.lbf = 1;
+                       if(!numb(&x.ub,&argc,&argv)) break;
+                       x.ubf = 1;
+                       break;
+               default:
+                       fprintf(stderr, "Bad agrument\n");
+                       exit(1);
+               }
+       }
+       if(auta&&!x.lbf) x.lb = 0;
+       readin();
+       getlim(&x);
+       getlim(&y);
+       i = (n+1)*sizeof(dx);
+       diag = (float *)malloc((unsigned)i);
+       r = (float *)malloc((unsigned)i);
+       if(r==NULL||!spline()) for(i=0;i<n;i++){
+               printf("%f ",x.val[i]);
+               printf("%f\n",y.val[i]); }
+}
+numb(np,argcp,argvp)
+       int *argcp;
+       float *np;
+       char ***argvp;{
+       double atof();
+       char c;
+       if(*argcp<=1) return(0);
+       c = (*argvp)[1][0];
+       if(!('0'<=c&&c<='9' || c=='-' || c== '.' )) return(0);
+       *np = atof((*argvp)[1]);
+       (*argcp)--;
+       (*argvp)++; 
+       return(1); }
+
diff --git a/usr/src/cmd/split.c b/usr/src/cmd/split.c
new file mode 100644 (file)
index 0000000..9493952
--- /dev/null
@@ -0,0 +1,81 @@
+#include <stdio.h>
+
+unsigned count = 1000;
+int    fnumber;
+char   fname[100];
+char   *ifil;
+char   *ofil;
+FILE   *is;
+FILE   *os;
+
+main(argc, argv)
+char *argv[];
+{
+       register i, c, f;
+       int iflg = 0;
+
+       for(i=1; i<argc; i++)
+               if(argv[i][0] == '-')
+                       switch(argv[i][1]) {
+               
+                       case '\0':
+                               iflg = 1;
+                               continue;
+               
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                       case '8':
+                       case '9':
+                               count = atoi(argv[i]+1);
+                               continue;
+                       }
+               else if(iflg)
+                       ofil = argv[i];
+               else {
+                       ifil = argv[i];
+                       iflg = 2;
+               }
+       if(iflg != 2)
+               is = stdin;
+       else
+               if((is=fopen(ifil,"r")) == NULL) {
+                       fprintf(stderr,"cannot open input\n");
+                       exit(1);
+               }
+       if(ofil == 0)
+               ofil = "x";
+
+loop:
+       f = 1;
+       for(i=0; i<count; i++)
+       do {
+               c = getc(is);
+               if(c == EOF) {
+                       if(f == 0)
+                               fclose(os);
+                       exit(0);
+               }
+               if(f) {
+                       for(f=0; ofil[f]; f++)
+                               fname[f] = ofil[f];
+                       fname[f++] = fnumber/26 + 'a';
+                       fname[f++] = fnumber%26 + 'a';
+                       fname[f] = '\0';
+                       fnumber++;
+                       if((os=fopen(fname,"w")) == NULL) {
+                               fprintf(stderr,"Cannot create output\n");
+                               exit(1);
+                       }
+                       f = 0;
+               }
+               putc(c, os);
+       } while(c != '\n');
+       fclose(os);
+       goto loop;
+}
diff --git a/usr/src/cmd/sum.c b/usr/src/cmd/sum.c
new file mode 100644 (file)
index 0000000..64acab1
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Sum bytes in file mod 2^16
+ */
+
+#include <stdio.h>
+
+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 (file)
index 0000000..3afb9b8
--- /dev/null
@@ -0,0 +1,5 @@
+main()
+{
+
+       sync();
+}
diff --git a/usr/src/cmd/tc.c b/usr/src/cmd/tc.c
new file mode 100644 (file)
index 0000000..be2ef07
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * Simulate typesetter on 4014
+*/
+
+#include <signal.h>
+#include <stdio.h>
+
+#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/test.c b/usr/src/cmd/test.c
new file mode 100644 (file)
index 0000000..fcd3dac
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ *     test expression
+ *     [ expression ]
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#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, "-ge"))
+               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 (file)
index 0000000..5c63d66
--- /dev/null
@@ -0,0 +1,78 @@
+/* time command */
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/times.h>
+
+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 (file)
index 0000000..715b6a0
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * optimize output for Tek 4014
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+#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;
+}
diff --git a/usr/src/cmd/touch.c b/usr/src/cmd/touch.c
new file mode 100644 (file)
index 0000000..33bcc50
--- /dev/null
@@ -0,0 +1,70 @@
+#include <stdio.h>
+
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+int i;
+static int force = 1;
+
+for(i = 1 ; i < argc ; ++i)
+       if( strcmp(argv[i], "-c") )
+               touch(force, argv[i]);
+       else
+               force = 0;
+}
+
+
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+touch(force, name)
+int force;
+char *name;
+{
+struct stat stbuff;
+char junk[1];
+int fd;
+
+if( stat(name,&stbuff) < 0)
+       if(force)
+               goto create;
+       else
+               {
+               fprintf(stderr, "touch: file %s does not exist.\n", name);
+               return;
+               }
+
+if(stbuff.st_size == 0)
+       goto create;
+
+if( (fd = open(name, 2)) < 0)
+       goto bad;
+
+if( read(fd, junk, 1) < 1)
+       {
+       close(fd);
+       goto bad;
+       }
+lseek(fd, 0L, 0);
+if( write(fd, junk, 1) < 1 )
+       {
+       close(fd);
+       goto bad;
+       }
+close(fd);
+return;
+
+bad:
+       fprintf(stderr, "Cannot touch %s\n", name);
+       return;
+
+create:
+       if( (fd = creat(name, 0666)) < 0)
+               goto bad;
+       close(fd);
+}
diff --git a/usr/src/cmd/tr.c b/usr/src/cmd/tr.c
new file mode 100644 (file)
index 0000000..01395ba
--- /dev/null
@@ -0,0 +1,132 @@
+#include <stdio.h>
+
+/* tr - transliterate data stream */
+int    dflag   = 0;
+int    sflag   = 0;
+int    cflag = 0;
+int    save    = 0;
+char   code[256];
+char   squeez[256];
+char   vect[256];
+struct string { int last, max; char *p; } string1, string2;
+
+main(argc,argv)
+char **argv;
+{
+       register i;
+       int j;
+       register c, d;
+       char *compl;
+       int lastd;
+
+       string1.last = string2.last = 0;
+       string1.max = string2.max = 0;
+       string1.p = string2.p = "";
+
+       if(--argc>0) {
+               argv++;
+               if(*argv[0]=='-'&&argv[0][1]!=0) {
+                       while(*++argv[0])
+                               switch(*argv[0]) {
+                               case 'c':
+                                       cflag++;
+                                       continue;
+                               case 'd':
+                                       dflag++;
+                                       continue;
+                               case 's':
+                                       sflag++;
+                                       continue;
+                               }
+                       argc--;
+                       argv++;
+               }
+       }
+       if(argc>0) string1.p = argv[0];
+       if(argc>1) string2.p = argv[1];
+       for(i=0; i<256; i++)
+               code[i] = vect[i] = 0;
+       if(cflag) {
+               while(c = next(&string1))
+                       vect[c&0377] = 1;
+               j = 0;
+               for(i=1; i<256; i++)
+                       if(vect[i]==0) vect[j++] = i;
+               vect[j] = 0;
+               compl = vect;
+       }
+       for(i=0; i<256; i++)
+               squeez[i] = 0;
+       lastd = 0;
+       for(;;){
+               if(cflag) c = *compl++;
+               else c = next(&string1);
+               if(c==0) break;
+               d = next(&string2);
+               if(d==0) d = lastd;
+               else lastd = d;
+               squeez[d&0377] = 1;
+               code[c&0377] = dflag?1:d;
+       }
+       while(d = next(&string2))
+               squeez[d&0377] = 1;
+       squeez[0] = 1;
+       for(i=0;i<256;i++) {
+               if(code[i]==0) code[i] = i;
+               else if(dflag) code[i] = 0;
+       }
+
+       while((c=getc(stdin)) != EOF ) {
+               if(c == 0) continue;
+               if(c = code[c&0377]&0377)
+                       if(!sflag || c!=save || !squeez[c&0377])
+                               putchar(save = c);
+       }
+       exit(0);
+}
+
+next(s)
+struct string *s;
+{
+
+again:
+       if(s->max) {
+               if(s->last++ < s->max)
+                       return(s->last);
+               s->max = s->last = 0;
+       }
+       if(s->last && *s->p=='-') {
+               nextc(s);
+               s->max = nextc(s);
+               if(s->max==0) {
+                       s->p--;
+                       return('-');
+               }
+               if(s->max < s->last)  {
+                       s->last = s->max-1;
+                       return('-');
+               }
+               goto again;
+       }
+       return(s->last = nextc(s));
+}
+
+nextc(s)
+struct string *s;
+{
+       register c, i, n;
+
+       c = *s->p++;
+       if(c=='\\') {
+               i = n = 0;
+               while(i<3 && (c = *s->p)>='0' && c<='7') {
+                       n = n*8 + c - '0';
+                       i++;
+                       s->p++;
+               }
+               if(i>0) c = n;
+               else c = *s->p++;
+       }
+       if(c==0) *--s->p = 0;
+       return(c&0377);
+}
diff --git a/usr/src/cmd/true.sh b/usr/src/cmd/true.sh
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/usr/src/cmd/tsort.c b/usr/src/cmd/tsort.c
new file mode 100644 (file)
index 0000000..d876a5e
--- /dev/null
@@ -0,0 +1,205 @@
+/*     topological sort
+ *     input is sequence of pairs of items (blank-free strings)
+ *     nonidentical pair is a directed edge in graph
+ *     identical pair merely indicates presence of node
+ *     output is ordered list of items consistent with
+ *     the partial ordering specified by the graph
+*/
+#include "stdio.h"
+
+/*     the nodelist always has an empty element at the end to
+ *     make it easy to grow in natural order
+ *     states of the "live" field:*/
+#define DEAD 0 /* already printed*/
+#define LIVE 1 /* not yet printed*/
+#define VISITED 2      /*used only in findloop()*/
+
+struct nodelist {
+       struct nodelist *nextnode;
+       struct predlist *inedges;
+       char *name;
+       int live;
+} firstnode = {NULL, NULL, NULL, DEAD};
+
+/*     a predecessor list tells all the immediate
+ *     predecessors of a given node
+*/
+struct predlist {
+       struct predlist *nextpred;
+       struct nodelist *pred;
+};
+
+struct nodelist *index();
+struct nodelist *findloop();
+struct nodelist *mark();
+char *malloc();
+char *empty = "";
+
+/*     the first for loop reads in the graph,
+ *     the second prints out the ordering
+*/
+main(argc,argv)
+char **argv;
+{
+       register struct predlist *t;
+       FILE *input = stdin;
+       register struct nodelist *i, *j;
+       int x;
+       char precedes[50], follows[50];
+       if(argc>1) {
+               input = fopen(argv[1],"r");
+               if(input==NULL)
+                       error("cannot open ", argv[1]);
+       }
+       for(;;) {
+               x = fscanf(input,"%s%s",precedes, follows);
+               if(x==EOF)
+                       break;
+               if(x!=2)
+                       error("odd data",empty);
+               i = index(precedes);
+               j = index(follows);
+               if(i==j||present(i,j)) 
+                       continue;
+               t = (struct predlist *)malloc(sizeof(struct predlist));
+               t->nextpred = j->inedges;
+               t->pred = i;
+               j->inedges = t;
+       }
+       for(;;) {
+               x = 0;  /*anything LIVE on this sweep?*/
+               for(i= &firstnode; i->nextnode!=NULL; i=i->nextnode) {
+                       if(i->live==LIVE) {
+                               x = 1;
+                               if(!anypred(i))
+                                       break;
+                       }
+               }
+               if(x==0)
+                       break;
+               if(i->nextnode==NULL)
+                       i = findloop();
+               printf("%s\n",i->name);
+               i->live = DEAD;
+       }
+}
+
+/*     is i present on j's predecessor list?
+*/
+present(i,j)
+struct nodelist *i, *j;
+{
+       register struct predlist *t;
+       for(t=j->inedges; t!=NULL; t=t->nextpred)
+               if(t->pred==i)
+                       return(1);
+       return(0);
+}
+
+/*     is there any live predecessor for i?
+*/
+anypred(i)
+struct nodelist *i;
+{
+       register struct predlist *t;
+       for(t=i->inedges; t!=NULL; t=t->nextpred)
+               if(t->pred->live==LIVE)
+                       return(1);
+       return(0);
+}
+
+/*     turn a string into a node pointer
+*/
+struct nodelist *
+index(s)
+register char *s;
+{
+       register struct nodelist *i;
+       register char *t;
+       for(i= &firstnode; i->nextnode!=NULL; i=i->nextnode)
+               if(cmp(s,i->name))
+                       return(i);
+       for(t=s; *t; t++) ;
+       t = malloc((unsigned)(t+1-s));
+       i->nextnode = (struct nodelist *)malloc(sizeof(struct nodelist));
+       if(i->nextnode==NULL||t==NULL)
+               error("too many items",empty);
+       i->name = t;
+       i->live = LIVE;
+       i->nextnode->nextnode = NULL;
+       i->nextnode->inedges = NULL;
+       i->nextnode->live = DEAD;
+       while(*t++ = *s++);
+       return(i);
+}
+
+cmp(s,t)
+register char *s, *t;
+{
+       while(*s==*t) {
+               if(*s==0)
+                       return(1);
+               s++;
+               t++;
+       }
+       return(0);
+}
+
+error(s,t)
+char *s, *t;
+{
+       note(s,t);
+       exit(1);
+}
+
+note(s,t)
+char *s,*t;
+{
+       fprintf(stderr,"tsort: %s%s\n",s,t);
+}
+
+/*     given that there is a cycle, find some
+ *     node in it
+*/
+struct nodelist *
+findloop()
+{
+       register struct nodelist *i, *j;
+       for(i= &firstnode; i->nextnode!=NULL; i=i->nextnode)
+               if(i->live==LIVE)
+                       break;
+       note("cycle in data",empty);
+       i = mark(i);
+       if(i==NULL)
+               error("program error",empty);
+       for(j= &firstnode; j->nextnode!=NULL; j=j->nextnode)
+               if(j->live==VISITED)
+                       j->live = LIVE;
+       return(i);
+}
+
+/*     depth-first search of LIVE predecessors
+ *     to find some element of a cycle;
+ *     VISITED is a temporary state recording the
+ *     visits of the search
+*/
+struct nodelist *
+mark(i)
+register struct nodelist *i;
+{
+       register struct nodelist *j;
+       register struct predlist *t;
+       if(i->live==DEAD)
+               return(NULL);
+       if(i->live==VISITED)
+               return(i);
+       i->live = VISITED;
+       for(t=i->inedges; t!=NULL; t=t->nextpred) {
+               j = mark(t->pred);
+               if(j!=NULL) {
+                       note(i->name,empty);
+                       return(j);
+               }
+       }
+       return(NULL);
+}
diff --git a/usr/src/cmd/tty.c b/usr/src/cmd/tty.c
new file mode 100644 (file)
index 0000000..cedc61a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Type tty name
+ */
+
+char   *ttyname();
+
+main(argc, argv)
+char **argv;
+{
+       register char *p;
+
+       p = ttyname(0);
+       if(argc==2 && !strcmp(argv[1], "-s"))
+               ;
+       else
+               printf("%s\n", (p? p: "not a tty"));
+       exit(p? 0: 1);
+}
diff --git a/usr/src/cmd/umount.c b/usr/src/cmd/umount.c
new file mode 100644 (file)
index 0000000..008c2d1
--- /dev/null
@@ -0,0 +1,54 @@
+#define        NMOUNT  16
+#define        NAMSIZ  32
+
+struct mtab {
+       char    file[NAMSIZ];
+       char    spec[NAMSIZ];
+} mtab[NMOUNT];
+
+main(argc, argv)
+char **argv;
+{
+       register struct mtab *mp;
+       register char *p1, *p2;
+       int mf;
+
+       sync();
+       mf = open("/etc/mtab", 0);
+       read(mf, (char *)mtab, NMOUNT*2*NAMSIZ);
+       if(argc != 2) {
+               printf("arg count\n");
+               return(1);
+       }
+       if (umount(argv[1]) < 0) {
+               perror("umount");
+               return(1);
+       }
+       p1 = argv[1];
+       while(*p1++)
+               ;
+       p1--;
+       while(*--p1 == '/')
+               *p1 = '\0';
+       while(p1 > argv[1] && *--p1 != '/')
+               ;
+       if(*p1 == '/')
+               p1++;
+       argv[1] = p1;
+       for (mp = mtab; mp < &mtab[NMOUNT]; mp++) {
+               p1 = argv[1];
+               p2 = &mp->spec[0];
+               while (*p1++ == *p2)
+                       if (*p2++ == 0) {
+                               for (p1 = mp->file; p1 < &mp->file[NAMSIZ*2];)
+                                       *p1++ = 0;
+                               mp = &mtab[NMOUNT];
+                               while ((--mp)->file[0] == 0);
+                               mf = creat("/etc/mtab", 0644);
+                               write(mf, (char *)mtab, (mp-mtab+1)*2*NAMSIZ);
+                               return(0);
+                       }
+       }
+       printf("%s not in mount table\n", argv[1]);
+       return(1);
+}
diff --git a/usr/src/cmd/uniq.c b/usr/src/cmd/uniq.c
new file mode 100644 (file)
index 0000000..36f1001
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Deal with duplicated lines in a file
+ */
+#include <stdio.h>
+#include <ctype.h>
+int    fields;
+int    letters;
+int    linec;
+char   mode;
+int    uniq;
+char   *skip();
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       static char b1[1000], b2[1000];
+
+       while(argc > 1) {
+               if(*argv[1] == '-') {
+                       if (isdigit(argv[1][1]))
+                               fields = atoi(&argv[1][1]);
+                       else mode = argv[1][1];
+                       argc--;
+                       argv++;
+                       continue;
+               }
+               if(*argv[1] == '+') {
+                       letters = atoi(&argv[1][1]);
+                       argc--;
+                       argv++;
+                       continue;
+               }
+               if (freopen(argv[1], "r", stdin) == NULL)
+                       printe("cannot open %s\n", argv[1]);
+               break;
+       }
+       if(argc > 2 && freopen(argv[2], "w", stdout) == NULL)
+               printe("cannot create %s\n", argv[2]);
+
+       if(gline(b1))
+               exit(0);
+       for(;;) {
+               linec++;
+               if(gline(b2)) {
+                       pline(b1);
+                       exit(0);
+               }
+               if(!equal(b1, b2)) {
+                       pline(b1);
+                       linec = 0;
+                       do {
+                               linec++;
+                               if(gline(b1)) {
+                                       pline(b2);
+                                       exit(0);
+                               }
+                       } while(equal(b1, b2));
+                       pline(b2);
+                       linec = 0;
+               }
+       }
+}
+
+gline(buf)
+register char buf[];
+{
+       register c;
+
+       while((c = getchar()) != '\n') {
+               if(c == EOF)
+                       return(1);
+               *buf++ = c;
+       }
+       *buf = 0;
+       return(0);
+}
+
+pline(buf)
+register char buf[];
+{
+
+       switch(mode) {
+
+       case 'u':
+               if(uniq) {
+                       uniq = 0;
+                       return;
+               }
+               break;
+
+       case 'd':
+               if(uniq) break;
+               return;
+
+       case 'c':
+               printf("%4d ", linec);
+       }
+       uniq = 0;
+       fputs(buf, stdout);
+       putchar('\n');
+}
+
+equal(b1, b2)
+register char b1[], b2[];
+{
+       register char c;
+
+       b1 = skip(b1);
+       b2 = skip(b2);
+       while((c = *b1++) != 0)
+               if(c != *b2++) return(0);
+       if(*b2 != 0)
+               return(0);
+       uniq++;
+       return(1);
+}
+
+char *
+skip(s)
+register char *s;
+{
+       register nf, nl;
+
+       nf = nl = 0;
+       while(nf++ < fields) {
+               while(*s == ' ' || *s == '\t')
+                       s++;
+               while( !(*s == ' ' || *s == '\t' || *s == 0) ) 
+                       s++;
+       }
+       while(nl++ < letters && *s != 0) 
+                       s++;
+       return(s);
+}
+
+printe(p,s)
+char *p,*s;
+{
+       fprintf(stderr, p, s);
+       exit(1);
+}
diff --git a/usr/src/cmd/units.c b/usr/src/cmd/units.c
new file mode 100644 (file)
index 0000000..2cb4996
--- /dev/null
@@ -0,0 +1,465 @@
+#include <stdio.h>
+
+#define        NDIM    10
+#define        NTAB    601
+char   *dfile  = "/usr/lib/units";
+char   *unames[NDIM];
+double getflt();
+int    fperr();
+struct table   *hash();
+struct unit
+{
+       double  factor;
+       char    dim[NDIM];
+};
+
+struct table
+{
+       double  factor;
+       char    dim[NDIM];
+       char    *name;
+} table[NTAB];
+char   names[NTAB*10];
+struct prefix
+{
+       double  factor;
+       char    *pname;
+} prefix[] = 
+{
+       1e-18,  "atto",
+       1e-15,  "femto",
+       1e-12,  "pico",
+       1e-9,   "nano",
+       1e-6,   "micro",
+       1e-3,   "milli",
+       1e-2,   "centi",
+       1e-1,   "deci",
+       1e1,    "deka",
+       1e2,    "hecta",
+       1e2,    "hecto",
+       1e3,    "kilo",
+       1e6,    "mega",
+       1e6,    "meg",
+       1e9,    "giga",
+       1e12,   "tera",
+       0.0,    0
+};
+FILE   *inp;
+int    fperrc;
+int    peekc;
+int    dumpflg;
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       register char *file;
+       struct unit u1, u2;
+       double f;
+
+       if(argc>1 && *argv[1]=='-') {
+               argc--;
+               argv++;
+               dumpflg++;
+       }
+       file = dfile;
+       if(argc > 1)
+               file = argv[1];
+       if ((inp = fopen(file, "r")) == NULL) {
+               printf("no table\n");
+               exit(1);
+       }
+       signal(8, fperr);
+       init();
+
+loop:
+       fperrc = 0;
+       printf("you have: ");
+       if(convr(&u1))
+               goto loop;
+       if(fperrc)
+               goto fp;
+loop1:
+       printf("you want: ");
+       if(convr(&u2))
+               goto loop1;
+       for(i=0; i<NDIM; i++)
+               if(u1.dim[i] != u2.dim[i])
+                       goto conform;
+       f = u1.factor/u2.factor;
+       if(fperrc)
+               goto fp;
+       printf("\t* %e\n", f);
+       printf("\t/ %e\n", 1./f);
+       goto loop;
+
+conform:
+       if(fperrc)
+               goto fp;
+       printf("conformability\n");
+       units(&u1);
+       units(&u2);
+       goto loop;
+
+fp:
+       printf("underflow or overflow\n");
+       goto loop;
+}
+
+units(up)
+struct unit *up;
+{
+       register struct unit *p;
+       register f, i;
+
+       p = up;
+       printf("\t%e ", p->factor);
+       f = 0;
+       for(i=0; i<NDIM; i++)
+               f |= pu(p->dim[i], i, f);
+       if(f&1) {
+               putchar('/');
+               f = 0;
+               for(i=0; i<NDIM; i++)
+                       f |= pu(-p->dim[i], i, f);
+       }
+       putchar('\n');
+}
+
+pu(u, i, f)
+{
+
+       if(u > 0) {
+               if(f&2)
+                       putchar('-');
+               if(unames[i])
+                       printf("%s", unames[i]); else
+                       printf("*%c*", i+'a');
+               if(u > 1)
+                       putchar(u+'0');
+                       return(2);
+       }
+       if(u < 0)
+               return(1);
+       return(0);
+}
+
+convr(up)
+struct unit *up;
+{
+       register struct unit *p;
+       register c;
+       register char *cp;
+       char name[20];
+       int den, err;
+
+       p = up;
+       for(c=0; c<NDIM; c++)
+               p->dim[c] = 0;
+       p->factor = getflt();
+       if(p->factor == 0.)
+               p->factor = 1.0;
+       err = 0;
+       den = 0;
+       cp = name;
+
+loop:
+       switch(c=get()) {
+
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+       case '-':
+       case '/':
+       case ' ':
+       case '\t':
+       case '\n':
+               if(cp != name) {
+                       *cp++ = 0;
+                       cp = name;
+                       err |= lookup(cp, p, den, c);
+               }
+               if(c == '/')
+                       den++;
+               if(c == '\n')
+                       return(err);
+               goto loop;
+       }
+       *cp++ = c;
+       goto loop;
+}
+
+lookup(name, up, den, c)
+char *name;
+struct unit *up;
+{
+       register struct unit *p;
+       register struct table *q;
+       register i;
+       char *cp1, *cp2;
+       double e;
+
+       p = up;
+       e = 1.0;
+
+loop:
+       q = hash(name);
+       if(q->name) {
+               l1:
+               if(den) {
+                       p->factor /= q->factor*e;
+                       for(i=0; i<NDIM; i++)
+                               p->dim[i] -= q->dim[i];
+               } else {
+                       p->factor *= q->factor*e;
+                       for(i=0; i<NDIM; i++)
+                               p->dim[i] += q->dim[i];
+               }
+               if(c >= '2' && c <= '9') {
+                       c--;
+                       goto l1;
+               }
+               return(0);
+       }
+       for(i=0; cp1 = prefix[i].pname; i++) {
+               cp2 = name;
+               while(*cp1 == *cp2++)
+                       if(*cp1++ == 0) {
+                               cp1--;
+                               break;
+                       }
+               if(*cp1 == 0) {
+                       e *= prefix[i].factor;
+                       name = cp2-1;
+                       goto loop;
+               }
+       }
+       for(cp1 = name; *cp1; cp1++);
+       if(cp1 > name+1 && *--cp1 == 's') {
+               *cp1 = 0;
+               goto loop;
+       }
+       printf("cannot recognize %s\n", name);
+       return(1);
+}
+
+equal(s1, s2)
+char *s1, *s2;
+{
+       register char *c1, *c2;
+
+       c1 = s1;
+       c2 = s2;
+       while(*c1++ == *c2)
+               if(*c2++ == 0)
+                       return(1);
+       return(0);
+}
+
+init()
+{
+       register char *cp;
+       register struct table *tp, *lp;
+       int c, i, f, t;
+       char *np;
+
+       cp = names;
+       for(i=0; i<NDIM; i++) {
+               np = cp;
+               *cp++ = '*';
+               *cp++ = i+'a';
+               *cp++ = '*';
+               *cp++ = 0;
+               lp = hash(np);
+               lp->name = np;
+               lp->factor = 1.0;
+               lp->dim[i] = 1;
+       }
+       lp = hash("");
+       lp->name = cp-1;
+       lp->factor = 1.0;
+
+l0:
+       c = get();
+       if(c == 0) {
+               printf("%l units; %l bytes\n\n", i, cp-names);
+               if(dumpflg)
+               for(tp = &table[0]; tp < &table[NTAB]; tp++) {
+                       if(tp->name == 0)
+                               continue;
+                       printf("%s", tp->name);
+                       units(tp);
+               }
+               fclose(inp);
+               inp = stdin;
+               return;
+       }
+       if(c == '/') {
+               while(c != '\n' && c != 0)
+                       c = get();
+               goto l0;
+       }
+       if(c == '\n')
+               goto l0;
+       np = cp;
+       while(c != ' ' && c != '\t') {
+               *cp++ = c;
+               c = get();
+               if (c==0)
+                       goto l0;
+               if(c == '\n') {
+                       *cp++ = 0;
+                       tp = hash(np);
+                       if(tp->name)
+                               goto redef;
+                       tp->name = np;
+                       tp->factor = lp->factor;
+                       for(c=0; c<NDIM; c++)
+                               tp->dim[c] = lp->dim[c];
+                       i++;
+                       goto l0;
+               }
+       }
+       *cp++ = 0;
+       lp = hash(np);
+       if(lp->name)
+               goto redef;
+       convr(lp);
+       lp->name = np;
+       f = 0;
+       i++;
+       if(lp->factor != 1.0)
+               goto l0;
+       for(c=0; c<NDIM; c++) {
+               t = lp->dim[c];
+               if(t>1 || (f>0 && t!=0))
+                       goto l0;
+               if(f==0 && t==1) {
+                       if(unames[c])
+                               goto l0;
+                       f = c+1;
+               }
+       }
+       if(f>0)
+               unames[f-1] = np;
+       goto l0;
+
+redef:
+       printf("redefinition %s\n", np);
+       goto l0;
+}
+
+double
+getflt()
+{
+       register c, i, dp;
+       double d, e;
+       int f;
+
+       d = 0.;
+       dp = 0;
+       do
+               c = get();
+       while(c == ' ' || c == '\t');
+
+l1:
+       if(c >= '0' && c <= '9') {
+               d = d*10. + c-'0';
+               if(dp)
+                       dp++;
+               c = get();
+               goto l1;
+       }
+       if(c == '.') {
+               dp++;
+               c = get();
+               goto l1;
+       }
+       if(dp)
+               dp--;
+       if(c == '+' || c == '-') {
+               f = 0;
+               if(c == '-')
+                       f++;
+               i = 0;
+               c = get();
+               while(c >= '0' && c <= '9') {
+                       i = i*10 + c-'0';
+                       c = get();
+               }
+               if(f)
+                       i = -i;
+               dp -= i;
+       }
+       e = 1.;
+       i = dp;
+       if(i < 0)
+               i = -i;
+       while(i--)
+               e *= 10.;
+       if(dp < 0)
+               d *= e; else
+               d /= e;
+       if(c == '|')
+               return(d/getflt());
+       peekc = c;
+       return(d);
+}
+
+get()
+{
+       register c;
+
+       if(c=peekc) {
+               peekc = 0;
+               return(c);
+       }
+       c = getc(inp);
+       if (c == EOF) {
+               if (inp == stdin) {
+                       printf("\n");
+                       exit(0);
+               }
+               return(0);
+       }
+       return(c);
+}
+
+struct table *
+hash(name)
+char *name;
+{
+       register struct table *tp;
+       register char *np;
+       register unsigned h;
+
+       h = 0;
+       np = name;
+       while(*np)
+               h = h*57 + *np++ - '0';
+       if( ((int)h)<0) h= -(int)h;
+       h %= NTAB;
+       tp = &table[h];
+l0:
+       if(tp->name == 0)
+               return(tp);
+       if(equal(name, tp->name))
+               return(tp);
+       tp++;
+       if(tp >= &table[NTAB])
+               tp = table;
+       goto l0;
+}
+
+fperr()
+{
+
+       signal(8, fperr);
+       fperrc++;
+}
diff --git a/usr/src/cmd/update.c b/usr/src/cmd/update.c
new file mode 100644 (file)
index 0000000..85c0540
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Update the file system every 30 seconds.
+ * For cache benefit, open certain system directories.
+ */
+
+#include <signal.h>
+
+char *fillst[] = {
+       "/bin",
+       "/usr",
+       "/usr/bin",
+       0,
+};
+
+main()
+{
+       char **f;
+
+       if(fork())
+               exit(0);
+       close(0);
+       close(1);
+       close(2);
+       for(f = fillst; *f; f++)
+               open(*f, 0);
+       dosync();
+       for(;;)
+               pause();
+}
+
+dosync()
+{
+       sync();
+       signal(SIGALRM, dosync);
+       alarm(30);
+}
diff --git a/usr/src/cmd/wc.c b/usr/src/cmd/wc.c
new file mode 100644 (file)
index 0000000..3a20b27
--- /dev/null
@@ -0,0 +1,86 @@
+/* wc line and word count */
+
+#include <stdio.h>
+
+main(argc, argv)
+char **argv;
+{
+       int i, token;
+       register FILE *fp;
+       long linect, wordct, charct;
+       long tlinect=0, twordct=0, tcharct=0;
+       char *wd;
+       register int c;
+
+       wd = "lwc";
+       if(argc > 1 && *argv[1] == '-') {
+               wd = ++argv[1];
+               argc--;
+               argv++;
+       }
+
+       i = 1;
+       fp = stdin;
+       do {
+               if(argc>1 && (fp=fopen(argv[i], "r")) == NULL) {
+                       fprintf(stderr, "wc: can't open %s\n", argv[i]);
+                       continue;
+               }
+               linect = 0;
+               wordct = 0;
+               charct = 0;
+               token = 0;
+               for(;;) {
+                       c = getc(fp);
+                       if (c == EOF)
+                               break;
+                       charct++;
+                       if(' '<c&&c<0177) {
+                               if(!token) {
+                                       wordct++;
+                                       token++;
+                               }
+                               continue;
+                       }
+                       if(c=='\n')
+                               linect++;
+                       else if(c!=' '&&c!='\t')
+                               continue;
+                       token = 0;
+               }
+               /* print lines, words, chars */
+               wcp(wd, charct, wordct, linect);
+               if(argc>1) {
+                       printf(" %s\n", argv[i]);
+               } else
+                       printf("\n");
+               fclose(fp);
+               tlinect += linect;
+               twordct += wordct;
+               tcharct += charct;
+       } while(++i<argc);
+       if(argc > 2) {
+               wcp(wd, tcharct, twordct, tlinect);
+               printf(" total\n");
+       }
+       exit(0);
+}
+
+wcp(wd, charct, wordct, linect)
+register char *wd;
+long charct; long wordct; long linect;
+{
+       while (*wd) switch (*wd++) {
+       case 'l':
+               printf("%7ld", linect);
+               break;
+
+       case 'w':
+               printf("%7ld ", wordct);
+               break;
+
+       case 'c':
+               printf("%7ld", charct);
+               break;
+       }
+}
diff --git a/usr/src/cmd/who.c b/usr/src/cmd/who.c
new file mode 100644 (file)
index 0000000..27e0b1d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * who
+ */
+
+#include <stdio.h>
+#include <utmp.h>
+#include <pwd.h>
+struct utmp utmp;
+struct passwd *pw;
+struct passwd *getpwuid();
+
+char *ttyname(), *rindex(), *ctime(), *strcpy();
+main(argc, argv)
+char **argv;
+{
+       register char *tp, *s;
+       register FILE *fi;
+
+       s = "/etc/utmp";
+       if(argc == 2)
+               s = argv[1];
+       if (argc==3) {
+               tp = ttyname(0);
+               if (tp)
+                       tp = rindex(tp, '/') + 1;
+               else {  /* no tty - use best guess from passwd file */
+                       pw = getpwuid(getuid());
+                       strcpy(utmp.ut_name, pw?pw->pw_name: "?");
+                       strcpy(utmp.ut_line, "tty??");
+                       time(&utmp.ut_time);
+                       putline();
+                       exit(0);
+               }
+       }
+       if ((fi = fopen(s, "r")) == NULL) {
+               puts("who: cannot open utmp");
+               exit(1);
+       }
+       while (fread((char *)&utmp, sizeof(utmp), 1, fi) == 1) {
+               if(argc==3) {
+                       if (strcmp(utmp.ut_line, tp))
+                               continue;
+#ifdef vax
+                       printf("(Vax) ");
+#endif
+                       putline();
+                       exit(0);
+               }
+               if(utmp.ut_name[0] == '\0' && argc==1)
+                       continue;
+               putline();
+       }
+}
+
+putline()
+{
+       register char *cbuf;
+
+       printf("%-8.8s %-8.8s", utmp.ut_name, utmp.ut_line);
+       cbuf = ctime(&utmp.ut_time);
+       printf("%.12s\n", cbuf+4);
+}
diff --git a/usr/src/games/arithmetic.c b/usr/src/games/arithmetic.c
new file mode 100644 (file)
index 0000000..f369918
--- /dev/null
@@ -0,0 +1,215 @@
+#include <stdio.h>
+#include <signal.h>
+#define        MAX     100
+
+char   types[10];
+int    right[MAX];
+int    left[MAX];
+int    rights;
+int    wrongs;
+long   stvec;
+long   etvec;
+long   dtvec;
+
+main(argc,argv)
+char   *argv[];
+{
+       int range, k, dif, l;
+       char line[100];
+       int ans,pans,i,j,t;
+       char    dir,sense;
+       extern  delete();
+
+       signal(SIGINT, delete);
+
+       range = 11;
+       dif = 0;
+       while(argc > 1) {
+               switch(*argv[1]) {
+               case '+':
+               case '-':
+               case 'x':
+               case '/':
+                       while(types[dif] = argv[1][dif])
+                               dif++;
+                       break;
+
+               default:
+                       range = getnum(argv[1]) + 1;
+               }
+               argv++;
+               argc--;
+       }
+       if(range > MAX) {
+               printf("Range is too large.\n");
+               exit();
+       }
+
+       if(dif == 0) {
+               types[0] = '+';
+               types[1] = '-';
+               dif = 2;
+       }
+
+       for(i = 0; i < range; i++) {
+               left[i] = right[i] = i;
+       }
+       time(&stvec);
+       k = stvec;
+       srand(k);
+       k = 0;
+       l = 0;
+       goto start;
+
+loop:
+       if(++k%20 == 0)
+               score();
+
+start:
+       i = skrand(range);
+       j = skrand(range);
+       if(dif > 1)
+               l = random(dif);
+
+       switch(types[l]) {
+               case '+':
+               default:
+                       ans = left[i] + right[j];
+                       printf("%d + %d =   ", left[i], right[j]);
+                       break;
+
+               case '-':
+                       t = left[i] + right[j];
+                       ans = left[i];
+                       printf("%d - %d =   ", t, right[j]);
+                       break;
+
+               case 'x':
+                       ans = left[i] * right[j];
+                       printf("%d x %d =   ", left[i], right[j]);
+                       break;
+
+               case '/':
+                       while(right[j] == 0)
+                               j = random(range);
+                       t = left[i] * right[j] + random(right[j]);
+                       ans = left[i];
+                       printf("%d / %d =   ", t, right[j]);
+                       break;
+       }
+
+
+loop1:
+       getline(line);
+       dtvec += etvec - stvec;
+       if(line[0]=='\n') goto loop1;
+       pans = getnum(line);
+       if(pans == ans) {
+               printf("Right!\n");
+               rights++;
+               goto loop;
+       }
+       else {
+               printf("What?\n");
+               wrongs++;
+               if(range >= MAX)        goto loop1;
+               left[range] = left[i];
+               right[range++] = right[j];
+               goto loop1;
+       }
+}
+
+getline(s)
+char *s;
+{
+       register char   *rs;
+
+       rs = s;
+
+       while((*rs = getchar()) == ' ');
+       while(*rs != '\n')
+               if(*rs == 0)
+                       exit();
+               else if(rs >= &s[99]) {
+                       while((*rs = getchar()) != '\n')
+                               if(*rs == '\0') exit();
+               }
+               else
+                       *++rs = getchar();
+       while(*--rs == ' ')
+               *rs = '\n';
+}
+
+getnum(s)
+char *s;
+{
+       int     a;
+       char    c;
+
+       a = 0;
+       while((c = *s++) >= '0' && c <= '9') {
+               a = a*10 + c - '0';
+       }
+       return(a);
+}
+
+int arand;
+
+srand(n)
+{
+       arand = n&077774 | 01;
+}
+
+rand()         /*uniform on 0 to 2**13-1*/
+{
+
+       arand *= 3125;
+       arand &= 077777;
+       return(arand/4);
+}
+
+random(range)
+{
+       return(hmul(rand(), 8*range));
+}
+
+skrand(range){
+int temp;
+       temp = rand() + rand();
+       if(temp >017777) temp = 040000 - temp;
+       return(hmul(temp,8*range));
+       }
+
+/* 'hmul' returns the upper 16 bits of the product, where the operands
+   are assumed to be 16-bit integers. It replaces an old PDP-11 
+   assembler language subroutine. -- dks.
+*/
+hmul(a,b) { return(a*b >> 16); }
+score()
+{
+       time(&etvec);
+
+       printf("\n\nRights %d; Wrongs %d; Score %d%%\n", rights, wrongs,
+               (rights * 100)/(rights + wrongs));
+
+       if(rights == 0) return;
+       printf("Total time %ld seconds; %.1f seconds per problem\n\n\n",
+               etvec - stvec,
+               (etvec - stvec) / (rights + 0.));
+
+       sleep(3);
+       time(&dtvec);
+       stvec += dtvec - etvec;
+       return(0);
+}
+
+delete()
+{
+       if(rights + wrongs == 0.) {
+               printf("\n");
+               exit();
+       }
+       score();
+       exit();
+}
+
diff --git a/usr/src/games/bcd.c b/usr/src/games/bcd.c
new file mode 100644 (file)
index 0000000..55f8f43
--- /dev/null
@@ -0,0 +1,133 @@
+int chtab[] = {
+00000, /*   */
+03004, /* ! */
+02404, /* " */
+02040, /* sharp */
+02042, /* $ */
+02104, /* % */
+00001, /* & */
+03002, /* ' */
+02201, /* ( */
+02202, /* ) */
+02102, /* * */
+00005, /* + */
+02044, /* , */
+00002, /* - */
+02041, /* . */
+00014, /* / */
+00004, /* 0 */
+00010, /* 1 */
+00020, /* 2 */
+00040, /* 3 */
+00100, /* 4 */
+00200, /* 5 */
+00400, /* 6 */
+01000, /* 7 */
+02000, /* 8 */
+04000, /* 9 */
+02200, /* : */
+02402, /* ; */
+02401, /* < */
+02204, /* = */
+02400, /* > */
+03000, /* ? */
+02100, /* at */
+ 011,
+ 021,
+ 041,
+0101,
+0201,
+0401,
+01001,
+02001,
+04001,
+012,
+022,
+042,
+0102,
+0202,
+0402,
+01002,
+02002,
+02002,
+024,
+044,
+0104,
+0204,
+0404,
+01004,
+02004,
+04004,
+02020, /* [ */
+03001, /* \ */
+02101, /* ] */
+00006, /* ^ */
+02024 /* _ */
+};
+       char s[128];
+       char *sp = {&s[0]};
+main(argc, argv)
+char *argv[];
+{
+       char *spp;
+       int i;
+       int j;
+       int c;
+       int l;
+
+       if (argc<2) {
+               puts("% ");
+               while ((c=getchar())!='\0'&c!='\n')
+                       *sp++ = c;
+               *sp = 0;
+               sp = &s[0];
+       } else
+               sp = *++argv;
+       puts("\n\n\n\n");
+       puts(" ________________________________");
+       puts("________________\n");
+       spp = sp;
+       while(*spp++);
+       spp--;
+       l = spp - sp;
+       putchar('/');
+       puts(sp);
+       i = 49 - l;
+       while(--i>0) putchar(' ');
+       puts("|\n");
+       j = 0;
+       spp = sp;
+       while (j++<12) {
+               putchar('|');
+               i = 0;
+               spp = sp;
+               while (i<48) {
+                       if(i>l) c = 0;
+                       else c = *spp++ - 040;
+                       i++;
+                       if (c>='a'-040) c = c - 040;
+                       if (c<0 | c>137) c = 0;
+                       if ((chtab[c]>>(j-1))&1) 
+                               puts("[\b\ 1\ 1\ 1\ 1\ 1]");
+                       else
+                               putchar(j>3?'0'+j-3:' ');
+               }
+               puts("|\n");
+       }
+       putchar('|');
+       puts("____________");
+       puts("____________________________________");
+       puts("|\n");
+       puts("\n\n\n\n");
+}
+
+puts(ss) char *ss; {
+       int i;
+       char t;
+       i = 0;
+       while(t = *ss++) {
+               if(t >= 'a' && t <= 'z')
+                       t += 'A'-'a';
+               putchar(t);
+       }
+}
diff --git a/usr/src/games/number.c b/usr/src/games/number.c
new file mode 100644 (file)
index 0000000..9b4d451
--- /dev/null
@@ -0,0 +1,199 @@
+int    flag;
+int max = 21;
+char   *card[] =
+{
+       "hundred",
+       "thousand",
+       "million",
+       "billion",
+       "trillion",
+       "quadrillion",
+       "quintillion",
+       "sextillion",
+       "septillion",
+       "octillion",
+       "nonillion",
+       "decillion",
+       "undecillion",
+       "duodecillion",
+       "tredecillion",
+       "quattuordecillion",
+       "quindecillion",
+       "sexdecillion",
+       "septendecillion",
+       "octodecillion",
+       "novemdecillion",
+       "vigintillion"
+};
+char *unit[] = {
+       "zero",
+       "one",
+       "two",
+       "three",
+       "four",
+       "five",
+       "six",
+       "seven",
+       "eight",
+       "nine"
+};
+char *teen[] = {
+       "ten",
+       "eleven",
+       "twelve",
+       "thirteen",
+       "fourteen",
+       "fifteen",
+       "sixteen",
+       "seventeen",
+       "eighteen",
+       "nineteen"
+};
+char *decade[] = {
+       "zero",
+       "ten",
+       "twenty",
+       "thirty",
+       "forty",
+       "fifty",
+       "sixty",
+       "seventy",
+       "eighty",
+       "ninety"
+};
+char   line[100];
+main()
+{
+       register c, i, fraction;
+       int r;
+
+
+       fraction = 0;
+       while(c = getchar()) {
+               if(!digit(c))  {
+                       fraction = (c == '.');
+                       putchar(c);
+                       continue;
+               }
+               if(fraction) {
+                       while(digit(c)) {
+                               putchar(' ');
+                               putchar(c);
+                               if(!(c=getchar()))
+                                       exit(1);
+                       }
+                       putchar(' ');
+                       goto out;
+               }
+
+               putchar(' ');
+               i = 0;
+               line[i++] = '0';
+               line[i++] = '0';
+               while(c == '0')
+                       if(!(c=getchar()))
+                               exit(1);
+               while(digit(c)) {
+                       if(i < 98)
+                               line[i++] = c;
+                       if(!(c=getchar()))
+                               exit(1);
+               }
+               line[i] = 0;
+               r = i/3;
+               if(r == 0) {
+                       print("zero");
+                       goto out;
+               }
+               conv(line+i-3*r, r);
+
+out:
+               fraction = (c == '.');
+               nline();
+               printf("...\n");
+               if(c != '\n')
+                       putchar(c);
+       }
+}
+
+conv(p, c)
+char *p;
+{
+
+       if(c > max) {
+               conv(p, c-max);
+               print(card[max]);
+               nline();
+               p += (c-max)*3;
+               c = max;
+       }
+       while(c > 1) {
+               c--;
+               conv(p, 1);
+               cprint(card[c]);
+               nline();
+               p += 3;
+       }
+       ones(p[0]);
+       cprint(card[0]);
+       tens(p);
+       ones(p[2]);
+}
+
+ones(d)
+{
+       if(d=='0')
+               return;
+       print(unit[d-'0']);
+}
+
+tens(p)
+char *p;
+{
+
+       switch(p[1]) {
+
+       case '0':
+               return;
+
+       case '1':
+               print(teen[p[2]-'0']);
+               p[2] = '0';
+               return;
+       }
+
+       print(decade[p[1]-'0']);
+}
+
+
+digit(c)
+{
+
+       if(c < '0' || c > '9')
+               return(0);
+       return(1);
+}
+
+nline()
+{
+
+       if(flag)
+               printf(".\n");
+       flag = 0;
+}
+
+cprint(s)
+{
+
+       if(flag)
+               print(s);
+}
+
+print(s)
+{
+
+       if(flag)
+               printf(" ");
+       printf(s);
+       flag = 1;
+}