Bell 32V development
authorTom London <tbl@research.uucp>
Mon, 6 Nov 1978 04:04:31 +0000 (23:04 -0500)
committerTom London <tbl@research.uucp>
Mon, 6 Nov 1978 04:04:31 +0000 (23:04 -0500)
Work on file usr/src/cmd/ar.c
Work on file usr/src/cmd/args.c
Work on file usr/src/cmd/accton.c
Work on file usr/src/cmd/arithmetic.c
Work on file usr/src/cmd/atrun.c
Work on file usr/src/cmd/basename.c
Work on file usr/src/cmd/at.c
Work on file usr/src/cmd/bcd.c
Work on file usr/src/cmd/bc.y
Work on file usr/src/cmd/cal.c
Work on file usr/src/cmd/call.c
Work on file usr/src/cmd/cat.c
Work on file usr/src/cmd/clri.c
Work on file usr/src/cmd/chgrp.c
Work on file usr/src/cmd/checkeq.c
Work on file usr/src/cmd/col.c
Work on file usr/src/cmd/chown.c
Work on file usr/src/cmd/cmp.c
Work on file usr/src/cmd/cp.c
Work on file usr/src/cmd/cpall.c
Work on file usr/src/cmd/cu.c
Work on file usr/src/cmd/cvtbl.c
Work on file usr/src/cmd/cron.c
Work on file usr/src/cmd/deroff.c
Work on file usr/src/cmd/dcheck.c
Work on file usr/src/cmd/diffh.c
Work on file usr/src/cmd/diff3/diff3.c
Work on file usr/src/cmd/draw.c
Work on file usr/src/cmd/echo.c
Work on file usr/src/cmd/dpr.c
Work on file usr/src/cmd/group.c
Work on file usr/src/cmd/init.c
Work on file usr/src/cmd/kill.c
Work on file usr/src/cmd/line.c
Work on file usr/src/cmd/lpd.c
Work on file usr/src/cmd/ls.c
Work on file usr/src/cmd/lpr.c
Work on file usr/src/cmd/mesg.c
Work on file usr/src/cmd/mknod.c
Work on file usr/src/cmd/mount.c
Work on file usr/src/cmd/mvall.c
Work on file usr/src/cmd/newgrp.c
Work on file usr/src/cmd/number.c
Work on file usr/src/cmd/od.c
Work on file usr/src/cmd/opr.c
Work on file usr/src/cmd/paste.c
Work on file usr/src/cmd/pcs.c
Work on file usr/src/cmd/pg.c
Work on file usr/src/cmd/rc.c
Work on file usr/src/cmd/rev.c
Work on file usr/src/cmd/rew.c
Work on file usr/src/cmd/rmdir.c
Work on file usr/src/cmd/sa.c
Work on file usr/src/cmd/sleep.c
Work on file usr/src/cmd/sort.c
Work on file usr/src/cmd/sp.c
Work on file usr/src/cmd/split.c
Work on file usr/src/cmd/sum.c
Work on file usr/src/cmd/sync.c
Work on file usr/src/cmd/tabs4.sh
Work on file usr/src/cmd/tabs8.sh
Work on file usr/src/cmd/tail.c
Work on file usr/src/cmd/tee.c
Work on file usr/src/cmd/test.c
Work on file usr/src/cmd/tk.c
Work on file usr/src/cmd/tr.c
Work on file usr/src/cmd/tsort.c
Work on file usr/src/cmd/umount.c
Work on file usr/src/cmd/und.c
Work on file usr/src/cmd/uniq.c
Work on file usr/src/cmd/update.c
Work on file usr/src/cmd/wc.c
Work on file usr/src/cmd/write.c
Work on file usr/src/cmd/yes.c

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

74 files changed:
usr/src/cmd/accton.c [new file with mode: 0644]
usr/src/cmd/ar.c [new file with mode: 0644]
usr/src/cmd/args.c [new file with mode: 0644]
usr/src/cmd/arithmetic.c [new file with mode: 0644]
usr/src/cmd/at.c [new file with mode: 0644]
usr/src/cmd/atrun.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/bcd.c [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/checkeq.c [new file with mode: 0644]
usr/src/cmd/chgrp.c [new file with mode: 0644]
usr/src/cmd/chown.c [new file with mode: 0644]
usr/src/cmd/clri.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/cp.c [new file with mode: 0644]
usr/src/cmd/cpall.c [new file with mode: 0644]
usr/src/cmd/cron.c [new file with mode: 0644]
usr/src/cmd/cu.c [new file with mode: 0644]
usr/src/cmd/cvtbl.c [new file with mode: 0644]
usr/src/cmd/dcheck.c [new file with mode: 0644]
usr/src/cmd/deroff.c [new file with mode: 0644]
usr/src/cmd/diff3/diff3.c [new file with mode: 0644]
usr/src/cmd/diffh.c [new file with mode: 0644]
usr/src/cmd/dpr.c [new file with mode: 0644]
usr/src/cmd/draw.c [new file with mode: 0644]
usr/src/cmd/echo.c [new file with mode: 0644]
usr/src/cmd/group.c [new file with mode: 0644]
usr/src/cmd/init.c [new file with mode: 0644]
usr/src/cmd/kill.c [new file with mode: 0644]
usr/src/cmd/line.c [new file with mode: 0644]
usr/src/cmd/lpd.c [new file with mode: 0644]
usr/src/cmd/lpr.c [new file with mode: 0644]
usr/src/cmd/ls.c [new file with mode: 0644]
usr/src/cmd/mesg.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/mvall.c [new file with mode: 0644]
usr/src/cmd/newgrp.c [new file with mode: 0644]
usr/src/cmd/number.c [new file with mode: 0644]
usr/src/cmd/od.c [new file with mode: 0644]
usr/src/cmd/opr.c [new file with mode: 0644]
usr/src/cmd/paste.c [new file with mode: 0644]
usr/src/cmd/pcs.c [new file with mode: 0644]
usr/src/cmd/pg.c [new file with mode: 0644]
usr/src/cmd/rc.c [new file with mode: 0644]
usr/src/cmd/rev.c [new file with mode: 0644]
usr/src/cmd/rew.c [new file with mode: 0644]
usr/src/cmd/rmdir.c [new file with mode: 0644]
usr/src/cmd/sa.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/sp.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/tabs4.sh [new file with mode: 0755]
usr/src/cmd/tabs8.sh [new file with mode: 0755]
usr/src/cmd/tail.c [new file with mode: 0644]
usr/src/cmd/tee.c [new file with mode: 0644]
usr/src/cmd/test.c [new file with mode: 0644]
usr/src/cmd/tk.c [new file with mode: 0644]
usr/src/cmd/tr.c [new file with mode: 0644]
usr/src/cmd/tsort.c [new file with mode: 0644]
usr/src/cmd/umount.c [new file with mode: 0644]
usr/src/cmd/und.c [new file with mode: 0644]
usr/src/cmd/uniq.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/write.c [new file with mode: 0644]
usr/src/cmd/yes.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/ar.c b/usr/src/cmd/ar.c
new file mode 100644 (file)
index 0000000..c499e68
--- /dev/null
@@ -0,0 +1,705 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ar.h>
+#include <signal.h>
+struct stat    stbuf;
+struct ar_hdr  arbuf;
+
+#define        SKIP    1
+#define        IODD    2
+#define        OODD    4
+#define        HEAD    8
+
+char   *man    =       { "mrxtdpq" };
+char   *opt    =       { "uvnbail" };
+
+int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
+int    sigdone();
+long   lseek();
+int    rcmd();
+int    dcmd();
+int    xcmd();
+int    tcmd();
+int    pcmd();
+int    mcmd();
+int    qcmd();
+int    (*comfun)();
+char   flg[26];
+char   **namv;
+int    namc;
+char   *arnam;
+char   *ponam;
+char   *tmpnam         =       { "/tmp/vXXXXX" };
+char   *tmp1nam        =       { "/tmp/v1XXXXX" };
+char   *tmp2nam        =       { "/tmp/v2XXXXX" };
+char   *tfnam;
+char   *tf1nam;
+char   *tf2nam;
+char   *file;
+char   name[16];
+int    af;
+int    tf;
+int    tf1;
+int    tf2;
+int    qf;
+int    bastate;
+char   buf[512];
+
+char   *trim();
+char   *mktemp();
+char   *ctime();
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       register char *cp;
+
+       for(i=0; signum[i]; i++)
+               if(signal(signum[i], SIG_IGN) != SIG_IGN)
+                       signal(signum[i], sigdone);
+       if(argc < 3)
+               usage();
+       cp = argv[1];
+       for(cp = argv[1]; *cp; cp++)
+       switch(*cp) {
+       case 'l':
+       case 'v':
+       case 'u':
+       case 'n':
+       case 'a':
+       case 'b':
+       case 'c':
+       case 'i':
+               flg[*cp - 'a']++;
+               continue;
+
+       case 'r':
+               setcom(rcmd);
+               continue;
+
+       case 'd':
+               setcom(dcmd);
+               continue;
+
+       case 'x':
+               setcom(xcmd);
+               continue;
+
+       case 't':
+               setcom(tcmd);
+               continue;
+
+       case 'p':
+               setcom(pcmd);
+               continue;
+
+       case 'm':
+               setcom(mcmd);
+               continue;
+
+       case 'q':
+               setcom(qcmd);
+               continue;
+
+       default:
+               fprintf(stderr, "ar: bad option `%c'\n", *cp);
+               done(1);
+       }
+       if(flg['l'-'a']) {
+               tmpnam = "vXXXXX";
+               tmp1nam = "v1XXXXX";
+               tmp2nam = "v2XXXXX";
+               }
+       if(flg['i'-'a'])
+               flg['b'-'a']++;
+       if(flg['a'-'a'] || flg['b'-'a']) {
+               bastate = 1;
+               ponam = trim(argv[2]);
+               argv++;
+               argc--;
+               if(argc < 3)
+                       usage();
+       }
+       arnam = argv[2];
+       namv = argv+3;
+       namc = argc-3;
+       if(comfun == 0) {
+               if(flg['u'-'a'] == 0) {
+                       fprintf(stderr, "ar: one of [%s] must be specified\n", man);
+                       done(1);
+               }
+               setcom(rcmd);
+       }
+       (*comfun)();
+       done(notfound());
+}
+
+setcom(fun)
+int (*fun)();
+{
+
+       if(comfun != 0) {
+               fprintf(stderr, "ar: only one of [%s] allowed\n", man);
+               done(1);
+       }
+       comfun = fun;
+}
+
+rcmd()
+{
+       register f;
+
+       init();
+       getaf();
+       while(!getdir()) {
+               bamatch();
+               if(namc == 0 || match()) {
+                       f = stats();
+                       if(f < 0) {
+                               if(namc)
+                                       fprintf(stderr, "ar: cannot open %s\n", file);
+                               goto cp;
+                       }
+                       if(flg['u'-'a'])
+                               if(stbuf.st_mtime <= arbuf.ar_date) {
+                                       close(f);
+                                       goto cp;
+                               }
+                       mesg('r');
+                       copyfil(af, -1, IODD+SKIP);
+                       movefil(f);
+                       continue;
+               }
+       cp:
+               mesg('c');
+               copyfil(af, tf, IODD+OODD+HEAD);
+       }
+       cleanup();
+}
+
+dcmd()
+{
+
+       init();
+       if(getaf())
+               noar();
+       while(!getdir()) {
+               if(match()) {
+                       mesg('d');
+                       copyfil(af, -1, IODD+SKIP);
+                       continue;
+               }
+               mesg('c');
+               copyfil(af, tf, IODD+OODD+HEAD);
+       }
+       install();
+}
+
+xcmd()
+{
+       register f;
+
+       if(getaf())
+               noar();
+       while(!getdir()) {
+               if(namc == 0 || match()) {
+                       f = creat(file, arbuf.ar_mode & 0777);
+                       if(f < 0) {
+                               fprintf(stderr, "ar: %s cannot create\n", file);
+                               goto sk;
+                       }
+                       mesg('x');
+                       copyfil(af, f, IODD);
+                       close(f);
+                       continue;
+               }
+       sk:
+               mesg('c');
+               copyfil(af, -1, IODD+SKIP);
+               if (namc > 0  &&  !morefil())
+                       done(0);
+       }
+}
+
+pcmd()
+{
+
+       if(getaf())
+               noar();
+       while(!getdir()) {
+               if(namc == 0 || match()) {
+                       if(flg['v'-'a']) {
+                               printf("\n<%s>\n\n", file);
+                               fflush(stdout);
+                       }
+                       copyfil(af, 1, IODD);
+                       continue;
+               }
+               copyfil(af, -1, IODD+SKIP);
+       }
+}
+
+mcmd()
+{
+
+       init();
+       if(getaf())
+               noar();
+       tf2nam = mktemp(tmp2nam);
+       close(creat(tf2nam, 0600));
+       tf2 = open(tf2nam, 2);
+       if(tf2 < 0) {
+               fprintf(stderr, "ar: cannot create third temp\n");
+               done(1);
+       }
+       while(!getdir()) {
+               bamatch();
+               if(match()) {
+                       mesg('m');
+                       copyfil(af, tf2, IODD+OODD+HEAD);
+                       continue;
+               }
+               mesg('c');
+               copyfil(af, tf, IODD+OODD+HEAD);
+       }
+       install();
+}
+
+tcmd()
+{
+
+       if(getaf())
+               noar();
+       while(!getdir()) {
+               if(namc == 0 || match()) {
+                       if(flg['v'-'a'])
+                               longt();
+                       printf("%s\n", trim(file));
+               }
+               copyfil(af, -1, IODD+SKIP);
+       }
+}
+
+qcmd()
+{
+       register i, f;
+
+       if (flg['a'-'a'] || flg['b'-'a']) {
+               fprintf(stderr, "ar: abi not allowed with q\n");
+               done(1);
+       }
+       getqf();
+       for(i=0; signum[i]; i++)
+               signal(signum[i], SIG_IGN);
+       lseek(qf, 0l, 2);
+       for(i=0; i<namc; i++) {
+               file = namv[i];
+               if(file == 0)
+                       continue;
+               namv[i] = 0;
+               mesg('q');
+               f = stats();
+               if(f < 0) {
+                       fprintf(stderr, "ar: %s cannot open\n", file);
+                       continue;
+               }
+               tf = qf;
+               movefil(f);
+               qf = tf;
+       }
+}
+
+init()
+{
+       static mbuf = ARMAG;
+
+       tfnam = mktemp(tmpnam);
+       close(creat(tfnam, 0600));
+       tf = open(tfnam, 2);
+       if(tf < 0) {
+               fprintf(stderr, "ar: cannot create temp file\n");
+               done(1);
+       }
+       if (write(tf, (char *)&mbuf, sizeof(int)) != sizeof(int))
+               wrerr();
+}
+
+getaf()
+{
+       int mbuf;
+
+       af = open(arnam, 0);
+       if(af < 0)
+               return(1);
+       if (read(af, (char *)&mbuf, sizeof(int)) != sizeof(int) || mbuf!=ARMAG) {
+               fprintf(stderr, "ar: %s not in archive format\n", arnam);
+               done(1);
+       }
+       return(0);
+}
+
+getqf()
+{
+       int mbuf;
+
+       if ((qf = open(arnam, 2)) < 0) {
+               if(!flg['c'-'a'])
+                       fprintf(stderr, "ar: creating %s\n", arnam);
+               close(creat(arnam, 0666));
+               if ((qf = open(arnam, 2)) < 0) {
+                       fprintf(stderr, "ar: cannot create %s\n", arnam);
+                       done(1);
+               }
+               mbuf = ARMAG;
+               if (write(qf, (char *)&mbuf, sizeof(int)) != sizeof(int))
+                       wrerr();
+       }
+       else if (read(qf, (char *)&mbuf, sizeof(int)) != sizeof(int)
+               || mbuf!=ARMAG) {
+               fprintf(stderr, "ar: %s not in archive format\n", arnam);
+               done(1);
+       }
+}
+
+usage()
+{
+       printf("usage: ar [%s][%s] archive files ...\n", opt, man);
+       done(1);
+}
+
+noar()
+{
+
+       fprintf(stderr, "ar: %s does not exist\n", arnam);
+       done(1);
+}
+
+sigdone()
+{
+       done(100);
+}
+
+done(c)
+{
+
+       if(tfnam)
+               unlink(tfnam);
+       if(tf1nam)
+               unlink(tf1nam);
+       if(tf2nam)
+               unlink(tf2nam);
+       exit(c);
+}
+
+notfound()
+{
+       register i, n;
+
+       n = 0;
+       for(i=0; i<namc; i++)
+               if(namv[i]) {
+                       fprintf(stderr, "ar: %s not found\n", namv[i]);
+                       n++;
+               }
+       return(n);
+}
+
+morefil()
+{
+       register i, n;
+
+       n = 0;
+       for(i=0; i<namc; i++)
+               if(namv[i])
+                       n++;
+       return(n);
+}
+
+cleanup()
+{
+       register i, f;
+
+       for(i=0; i<namc; i++) {
+               file = namv[i];
+               if(file == 0)
+                       continue;
+               namv[i] = 0;
+               mesg('a');
+               f = stats();
+               if(f < 0) {
+                       fprintf(stderr, "ar: %s cannot open\n", file);
+                       continue;
+               }
+               movefil(f);
+       }
+       install();
+}
+
+install()
+{
+       register i;
+
+       for(i=0; signum[i]; i++)
+               signal(signum[i], SIG_IGN);
+       if(af < 0)
+               if(!flg['c'-'a'])
+                       fprintf(stderr, "ar: creating %s\n", arnam);
+       close(af);
+       af = creat(arnam, 0666);
+       if(af < 0) {
+               fprintf(stderr, "ar: cannot create %s\n", arnam);
+               done(1);
+       }
+       if(tfnam) {
+               lseek(tf, 0l, 0);
+               while((i = read(tf, buf, 512)) > 0)
+                       if (write(af, buf, i) != i)
+                               wrerr();
+       }
+       if(tf2nam) {
+               lseek(tf2, 0l, 0);
+               while((i = read(tf2, buf, 512)) > 0)
+                       if (write(af, buf, i) != i)
+                               wrerr();
+       }
+       if(tf1nam) {
+               lseek(tf1, 0l, 0);
+               while((i = read(tf1, buf, 512)) > 0)
+                       if (write(af, buf, i) != i)
+                               wrerr();
+       }
+}
+
+/*
+ * insert the file 'file'
+ * into the temporary file
+ */
+movefil(f)
+{
+       register char *cp;
+       register i;
+
+       cp = trim(file);
+       for(i=0; i<14; i++)
+               if(arbuf.ar_name[i] = *cp)
+                       cp++;
+       arbuf.ar_size = stbuf.st_size;
+       arbuf.ar_date = stbuf.st_mtime;
+       arbuf.ar_uid = stbuf.st_uid;
+       arbuf.ar_gid = stbuf.st_gid;
+       arbuf.ar_mode = stbuf.st_mode;
+       copyfil(f, tf, OODD+HEAD);
+       close(f);
+}
+
+stats()
+{
+       register f;
+
+       f = open(file, 0);
+       if(f < 0)
+               return(f);
+       if(fstat(f, &stbuf) < 0) {
+               close(f);
+               return(-1);
+       }
+       return(f);
+}
+
+/*
+ * copy next file
+ * size given in arbuf
+ */
+copyfil(fi, fo, flag)
+{
+       register i, o;
+       int pe;
+
+       if(flag & HEAD)
+               if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf)
+                       wrerr();
+       pe = 0;
+       while(arbuf.ar_size > 0) {
+               i = o = 512;
+               if(arbuf.ar_size < i) {
+                       i = o = arbuf.ar_size;
+                       if(i&1) {
+                               if(flag & IODD)
+                                       i++;
+                               if(flag & OODD)
+                                       o++;
+                       }
+               }
+               if(read(fi, buf, i) != i)
+                       pe++;
+               if((flag & SKIP) == 0)
+                       if (write(fo, buf, o) != o)
+                               wrerr();
+               arbuf.ar_size -= 512;
+       }
+       if(pe)
+               phserr();
+}
+
+getdir()
+{
+       register i;
+
+       i = read(af, (char *)&arbuf, sizeof arbuf);
+       if(i != sizeof arbuf) {
+               if(tf1nam) {
+                       i = tf;
+                       tf = tf1;
+                       tf1 = i;
+               }
+               return(1);
+       }
+       for(i=0; i<14; i++)
+               name[i] = arbuf.ar_name[i];
+       file = name;
+       return(0);
+}
+
+match()
+{
+       register i;
+
+       for(i=0; i<namc; i++) {
+               if(namv[i] == 0)
+                       continue;
+               if(strcmp(trim(namv[i]), file) == 0) {
+                       file = namv[i];
+                       namv[i] = 0;
+                       return(1);
+               }
+       }
+       return(0);
+}
+
+bamatch()
+{
+       register f;
+
+       switch(bastate) {
+
+       case 1:
+               if(strcmp(file, ponam) != 0)
+                       return;
+               bastate = 2;
+               if(flg['a'-'a'])
+                       return;
+
+       case 2:
+               bastate = 0;
+               tf1nam = mktemp(tmp1nam);
+               close(creat(tf1nam, 0600));
+               f = open(tf1nam, 2);
+               if(f < 0) {
+                       fprintf(stderr, "ar: cannot create second temp\n");
+                       return;
+               }
+               tf1 = tf;
+               tf = f;
+       }
+}
+
+phserr()
+{
+
+       fprintf(stderr, "ar: phase error on %s\n", file);
+}
+
+mesg(c)
+{
+
+       if(flg['v'-'a'])
+               if(c != 'c' || flg['v'-'a'] > 1)
+                       printf("%c - %s\n", c, file);
+}
+
+char *
+trim(s)
+char *s;
+{
+       register char *p1, *p2;
+
+       for(p1 = s; *p1; p1++)
+               ;
+       while(p1 > s) {
+               if(*--p1 != '/')
+                       break;
+               *p1 = 0;
+       }
+       p2 = s;
+       for(p1 = s; *p1; p1++)
+               if(*p1 == '/')
+                       p2 = p1+1;
+       return(p2);
+}
+
+#define        IFMT    060000
+#define        ISARG   01000
+#define        LARGE   010000
+#define        SUID    04000
+#define        SGID    02000
+#define        ROWN    0400
+#define        WOWN    0200
+#define        XOWN    0100
+#define        RGRP    040
+#define        WGRP    020
+#define        XGRP    010
+#define        ROTH    04
+#define        WOTH    02
+#define        XOTH    01
+#define        STXT    01000
+
+longt()
+{
+       register char *cp;
+
+       pmode();
+       printf("%3d/%1d", arbuf.ar_uid, arbuf.ar_gid);
+       printf("%7D", arbuf.ar_size);
+       cp = ctime(&arbuf.ar_date);
+       printf(" %-12.12s %-4.4s ", cp+4, cp+20);
+}
+
+int    m1[] = { 1, ROWN, 'r', '-' };
+int    m2[] = { 1, WOWN, 'w', '-' };
+int    m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
+int    m4[] = { 1, RGRP, 'r', '-' };
+int    m5[] = { 1, WGRP, 'w', '-' };
+int    m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
+int    m7[] = { 1, ROTH, 'r', '-' };
+int    m8[] = { 1, WOTH, 'w', '-' };
+int    m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
+
+int    *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
+
+pmode()
+{
+       register int **mp;
+
+       for (mp = &m[0]; mp < &m[9];)
+               select(*mp++);
+}
+
+select(pairp)
+int *pairp;
+{
+       register int n, *ap;
+
+       ap = pairp;
+       n = *ap++;
+       while (--n>=0 && (arbuf.ar_mode&*ap++)==0)
+               ap++;
+       putchar(*ap);
+}
+
+wrerr()
+{
+       perror("ar write error");
+       done(1);
+}
diff --git a/usr/src/cmd/args.c b/usr/src/cmd/args.c
new file mode 100644 (file)
index 0000000..a519ef9
--- /dev/null
@@ -0,0 +1,25 @@
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       register int i;
+       register char *cp;
+
+       argc--;
+       for(i=1; i<=argc; i++) {
+               printf("%d:     ",i);
+               for(cp=argv[i]; *cp ; ++cp) {
+                       if (*cp&0200) putchar('@');
+                       *cp &= 0177;
+                       if (*cp=='@') putchar('@');
+                       putchar(*cp);
+               }
+               printf("\n");
+       }
+       exit(0);
+}
+
+putchar(c)
+{
+       write(1,&c,1);
+}
diff --git a/usr/src/cmd/arithmetic.c b/usr/src/cmd/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/cmd/at.c b/usr/src/cmd/at.c
new file mode 100644 (file)
index 0000000..bc5e60f
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * at time mon day
+ * at time wday
+ * at time wday 'week'
+ *
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+#include <signal.h>
+
+#define HOUR 100
+#define HALFDAY        (12*HOUR)
+#define DAY    (24*HOUR)
+#define THISDAY "/usr/spool/at"
+
+char *days[] = {
+       "sunday",
+       "monday",
+       "tuesday",
+       "wednesday",
+       "thursday",
+       "friday",
+       "saturday",
+};
+
+struct monstr {
+       char *mname; 
+       int mlen;
+} months[] = {
+       { "january", 31 },
+       { "february", 28 },
+       { "march", 31 },
+       { "april", 30 },
+       { "may", 31 },
+       { "june", 30 },
+       { "july", 31 },
+       { "august", 31 },
+       { "september", 30 },
+       { "october", 31 },
+       { "november", 30 },
+       { "december", 31 },
+       { 0, 0 },
+};
+
+char   fname[100];
+int    utime;  /* requested time in grains */
+int    now;    /* when is it */
+int    uday; /* day of year to be done */
+int    uyear; /* year */
+int    today; /* day of year today */
+FILE   *file;
+FILE   *ifile;
+char   **environ;
+char   *prefix();
+FILE   *popen();
+
+main(argc, argv)
+char **argv;
+{
+       extern onintr();
+       register c;
+       char pwbuf[100];
+       FILE *pwfil;
+       int larg;
+
+       /* argv[1] is the user's time: e.g.,  3AM */
+       /* argv[2] is a month name or day of week */
+       /* argv[3] is day of month or 'week' */
+       /* another argument might be an input file */
+       if (argc < 2) {
+               fprintf(stderr, "at: arg count\n");
+               exit(1);
+       }
+       makeutime(argv[1]);
+       larg = makeuday(argc,argv)+1;
+       if (uday==today && larg<=2 && utime<=now)
+               uday++;
+       c = uyear%4==0? 366: 365;
+       if (uday >= c) {
+               uday -= c;
+               uyear++;
+       }
+       filename(THISDAY, uyear, uday, utime);
+       ifile = stdin;
+       if (argc > larg)
+               ifile = fopen(argv[larg], "r");
+       if (ifile == NULL) {
+               fprintf(stderr, "at: cannot open input: %s\n", argv[larg]);
+               exit(1);
+       }
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, onintr);
+       file = fopen(fname, "a");
+       chmod(fname, 0644);
+       if (file == NULL) {
+               fprintf(stderr, "at: cannot open memo file\n");
+               exit(1);
+       }
+       if ((pwfil = popen("pwd", "r")) == NULL) {
+               fprintf(stderr, "at: can't execute pwd\n");
+               exit(1);
+       }
+       fgets(pwbuf, 100, pwfil);
+       pclose(pwfil);
+       fprintf(file, "cd %s", pwbuf);
+       if (environ) {
+               char **ep = environ;
+               while(*ep)
+                       fprintf(file, "%s\n", *ep++);
+       }
+       while((c = getc(ifile)) != EOF) {
+               putc(c, file);
+       }
+       exit(0);
+}
+
+makeutime(pp)
+char *pp; 
+{
+       register val;
+       register char *p;
+
+       /* p points to a user time */
+       p = pp;
+       val = 0;
+       while(isdigit(*p)) {
+               val = val*10+(*p++ -'0');
+       }
+       if (p-pp < 3)
+               val *= HOUR;
+
+       for (;;) {
+               switch(*p) {
+
+               case ':':
+                       ++p;
+                       if (isdigit(*p)) {
+                               if (isdigit(p[1])) {
+                                       val +=(10* *p + p[1] - 11*'0');
+                                       p += 2;
+                                       continue;
+                               }
+                       }
+                       fprintf(stderr, "at: bad time format:\n");
+                       exit(1);
+
+               case 'A':
+               case 'a':
+                       if (val >= HALFDAY+HOUR)
+                               val = DAY+1;  /* illegal */
+                       if (val >= HALFDAY && val <(HALFDAY+HOUR))
+                               val -= HALFDAY;
+                       break;
+
+               case 'P':
+               case 'p':
+                       if (val >= HALFDAY+HOUR)
+                               val = DAY+1;  /* illegal */
+                       if (val < HALFDAY)
+                               val += HALFDAY;
+                       break;
+
+               case 'n':
+               case 'N':
+                       val = HALFDAY;
+                       break;
+
+               case 'M':
+               case 'm':
+                       val = 0;
+                       break;
+
+
+               case '\0':
+               case ' ':
+                       /* 24 hour time */
+                       if (val == DAY)
+                               val -= DAY;
+                       break;
+
+               default:
+                       fprintf(stderr, "at: bad time format\n");
+                       exit(1);
+
+               }
+               break;
+       }
+       if (val < 0 || val >= DAY) {
+               fprintf(stderr, "at: time out of range\n");
+               exit(1);
+       }
+       if (val%HOUR >= 60) {
+               fprintf(stderr, "at: illegal minute field\n");
+               exit(1);
+       }
+       utime = val;
+}
+
+
+makeuday(argc,argv)
+char **argv;
+{
+       /* the presumption is that argv[2], argv[3] are either
+          month day OR weekday [week].  Returns either 2 or 3 as last
+          argument used */
+       /* first of all, what's today */
+       long tm;
+       int found = -1;
+       char **ps;
+       struct tm *detail, *localtime();
+       struct monstr *pt;
+
+       time(&tm);
+       detail = localtime(&tm);
+       uday = today = detail->tm_yday;
+       uyear = detail->tm_year;
+       now = detail->tm_hour*100+detail->tm_min;
+       if (argc<=2)
+               return(1);
+       /* is the next argument a month name ? */
+       for (pt=months; pt->mname; pt++) {
+               if (prefix(argv[2], pt->mname)) {
+                       if (found<0)
+                               found = pt-months;
+                       else {
+                               fprintf(stderr, "at: ambiguous month\n");
+                               exit(1);
+                       }
+               }
+       }
+       if (found>=0) {
+               if (argc<=3)
+                       return(2);
+               uday = atoi(argv[3]) - 1;
+               if (uday<0) {
+                       fprintf(stderr, "at: illegal day\n");
+                       exit(1);
+               }
+               while(--found>=0)
+                       uday += months[found].mlen;
+               if (detail->tm_year%4==0 && uday>59)
+                       uday += 1;
+               return(3);
+       }
+       /* not a month, try day of week */
+       found = -1;
+       for (ps=days; ps<days+7; ps++) {
+               if (prefix(argv[2], *ps)) {
+                       if (found<0)
+                               found = ps-days;
+                       else {
+                               fprintf(stderr, "at: ambiguous day of week\n");
+                               exit(1);
+                       }
+               }
+       }
+       if (found<0)
+               return(1);
+       /* find next day of this sort */
+       uday = found - detail->tm_wday;
+       if (uday<=0)
+               uday += 7;
+       uday += today;
+       if (argc>3 && strcmp("week", argv[3])==0) {
+               uday += 7;
+               return(3);
+       }
+       return(2);
+}
+
+char *
+prefix(begin, full)
+char *begin, *full;
+{
+       int c;
+       while (c = *begin++) {
+               if (isupper(c))
+                       c = tolower(c);
+               if (*full != c)
+                       return(0);
+               else
+                       full++;
+       }
+       return(full);
+}
+
+filename(dir, y, d, t)
+char *dir;
+{
+       register i;
+
+       for (i=0; ; i += 53) {
+               sprintf(fname, "%s/%02d.%03d.%04d.%02d", dir, y, d, t,
+                  (getpid()+i)%100);
+               if (access(fname, 0) == -1)
+                       return;
+       }
+}
+
+onintr()
+{
+       unlink(fname);
+       exit(1);
+}
diff --git a/usr/src/cmd/atrun.c b/usr/src/cmd/atrun.c
new file mode 100644 (file)
index 0000000..8b01bef
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Run programs submitted by at.
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <time.h>
+#include <sys/stat.h>
+
+# define DIR "/usr/spool/at"
+# define PDIR  "past"
+# define LASTF "/usr/spool/at/lasttimedone"
+
+int    nowtime;
+int    nowdate;
+int    nowyear;
+
+main(argc, argv)
+char **argv;
+{
+       int tt, day, year, uniq;
+       struct direct dirent;
+       FILE *dirf;
+
+       chdir(DIR);
+       makenowtime();
+       if ((dirf = fopen(".", "r")) == NULL) {
+               fprintf(stderr, "Cannot read at directory\n");
+               exit(1);
+       }
+       while (fread((char *)&dirent, sizeof(dirent), 1, dirf) == 1) {
+               if (dirent.d_ino==0)
+                       continue;
+               if (sscanf(dirent.d_name, "%2d.%3d.%4d.%2d", &year, &day, &tt, &uniq) != 4)
+                       continue;
+               if (nowyear < year)
+                       continue;
+               if (nowyear==year && nowdate < day)
+                       continue;
+               if (nowyear==year && nowdate==day && nowtime < tt)
+                       continue;
+               run(dirent.d_name);
+       }
+       fclose(dirf);
+       updatetime(nowtime);
+       exit(0);
+}
+
+makenowtime()
+{
+       long t;
+       struct tm *localtime();
+       register struct tm *tp;
+
+       time(&t);
+       tp = localtime(&t);
+       nowtime = tp->tm_hour*100 + tp->tm_min;
+       nowdate = tp->tm_yday;
+       nowyear = tp->tm_year;
+}
+
+updatetime(t)
+{
+       FILE *tfile;
+
+       tfile = fopen(LASTF, "w");
+       if (tfile == NULL) {
+               fprintf(stderr, "can't write lastfile\n");
+               exit(1);
+       }
+       fprintf(tfile, "%04d\n", t);
+}
+
+run(file)
+char *file;
+{
+       struct stat stbuf;
+       register pid, i;
+       char sbuf[64];
+
+       if (fork()!=0)
+               return;
+       for (i=0; i<15; i++)
+               close(i);
+       dup(dup(open("/dev/null", 0)));
+       sprintf(sbuf, "/bin/mv %.14s %s", file, PDIR);
+       system(sbuf);
+       chdir(PDIR);
+       if (stat(file, &stbuf) == -1)
+               exit(1);
+       setgid(stbuf.st_gid);
+       setuid(stbuf.st_uid);
+       if (pid = fork()) {
+               if (pid == -1)
+                       exit(1);
+               wait((int *)0);
+               unlink(file);
+               exit(0);
+       }
+       nice(3);
+       execl("/bin/sh", "sh", file, 0);
+       execl("/usr/bin/sh", "sh", file, 0);
+       fprintf(stderr, "Can't execl shell\n");
+       exit(1);
+}
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/bcd.c b/usr/src/cmd/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/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/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/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/clri.c b/usr/src/cmd/clri.c
new file mode 100644 (file)
index 0000000..d4da6de
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * clri filsys inumber ...
+ */
+
+#include <sys/types.h>
+#include <sys/ino.h>
+#define ISIZE  (sizeof(struct dinode))
+#define        BSIZE   512
+#define        NI      (BSIZE/ISIZE)
+struct ino
+{
+       char    junk[ISIZE];
+};
+struct ino     buf[NI];
+int    status;
+
+main(argc, argv)
+char *argv[];
+{
+       register i, f;
+       unsigned n;
+       int j, k;
+       long off;
+
+       if(argc < 3) {
+               printf("usage: clri filsys inumber ...\n");
+               exit(4);
+       }
+       f = open(argv[1], 2);
+       if(f < 0) {
+               printf("cannot open %s\n", argv[1]);
+               exit(4);
+       }
+       for(i=2; i<argc; i++) {
+               if(!isnumber(argv[i])) {
+                       printf("%s: is not a number\n", argv[i]);
+                       status = 1;
+                       continue;
+               }
+               n = atoi(argv[i]);
+               if(n == 0) {
+                       printf("%s: is zero\n", argv[i]);
+                       status = 1;
+                       continue;
+               }
+               off = ((n-1)/NI + 2) * (long)512;
+               lseek(f, off, 0);
+               if(read(f, (char *)buf, BSIZE) != BSIZE) {
+                       printf("%s: read error\n", argv[i]);
+                       status = 1;
+               }
+       }
+       if(status)
+               exit(status);
+       for(i=2; i<argc; i++) {
+               n = atoi(argv[i]);
+               printf("clearing %u\n", n);
+               off = ((n-1)/NI + 2) * (long)512;
+               lseek(f, off, 0);
+               read(f, (char *)buf, BSIZE);
+               j = (n-1)%NI;
+               for(k=0; k<ISIZE; k++)
+                       buf[j].junk[k] = 0;
+               lseek(f, off, 0);
+               write(f, (char *)buf, BSIZE);
+       }
+       exit(status);
+}
+
+isnumber(s)
+char *s;
+{
+       register c;
+
+       while(c = *s++)
+               if(c < '0' || c > '9')
+                       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/cp.c b/usr/src/cmd/cp.c
new file mode 100644 (file)
index 0000000..7af6362
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * cp oldfile newfile
+ */
+
+#define        BSIZE   512
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+struct stat    stbuf1, stbuf2;
+char   iobuf[BSIZE];
+
+main(argc, argv)
+char *argv[];
+{
+       register i, r;
+
+       if (argc < 3) 
+               goto usage;
+       if (argc > 3) {
+               if (stat(argv[argc-1], &stbuf2) < 0)
+                       goto usage;
+               if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 
+                       goto usage;
+       }
+       r = 0;
+       for(i=1; i<argc-1;i++)
+               r |= copy(argv[i], argv[argc-1]);
+       exit(r);
+usage:
+       fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
+       exit(1);
+}
+
+copy(from, to)
+char *from, *to;
+{
+       int fold, fnew, n;
+       register char *p1, *p2, *bp;
+       int mode;
+       if ((fold = open(from, 0)) < 0) {
+               fprintf(stderr, "cp: cannot open %s\n", from);
+               return(1);
+       }
+       fstat(fold, &stbuf1);
+       mode = stbuf1.st_mode;
+       /* is target a directory? */
+       if (stat(to, &stbuf2) >=0 &&
+          (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
+               p1 = from;
+               p2 = to;
+               bp = iobuf;
+               while(*bp++ = *p2++)
+                       ;
+               bp[-1] = '/';
+               p2 = bp;
+               while(*bp = *p1++)
+                       if (*bp++ == '/')
+                               bp = p2;
+               to = iobuf;
+       }
+       if (stat(to, &stbuf2) >= 0) {
+               if (stbuf1.st_dev == stbuf2.st_dev &&
+                  stbuf1.st_ino == stbuf2.st_ino) {
+                       fprintf(stderr, "cp: cannot copy file to itself.\n");
+                       return(1);
+               }
+       }
+       if ((fnew = creat(to, mode)) < 0) {
+               fprintf(stderr, "cp: cannot create %s\n", to);
+               close(fold);
+               return(1);
+       }
+       while(n = read(fold,  iobuf,  BSIZE)) {
+               if (n < 0) {
+                       fprintf(stderr, "cp: read error\n");
+                       close(fold);
+                       close(fnew);
+                       return(1);
+               } else
+                       if (write(fnew, iobuf, n) != n) {
+                               fprintf(stderr, "cp: write error.\n");
+                               close(fold);
+                               close(fnew);
+                               return(1);
+                       }
+       }
+       close(fold);
+       close(fnew);
+       return(0);
+}
diff --git a/usr/src/cmd/cpall.c b/usr/src/cmd/cpall.c
new file mode 100644 (file)
index 0000000..d92d6e9
--- /dev/null
@@ -0,0 +1,29 @@
+char   buf[100];
+int    stat;
+
+main(argc, argv)
+char **argv;
+{
+       register i;
+       register char *c1, *c2;
+
+       if(argc < 3) {
+               write(2, "arg count\n", 10);
+               exit(1);
+       }
+       argc--;
+       c1 = buf;
+       c2 = argv[argc];
+       while(*c1++ = *c2++);
+       c1[-1] = '/';
+       *c1++ = '.';
+       *c1 = '\0';
+       for(i=1; i<argc; i++) {
+               if(fork()==0) {
+                       execl("/bin/cp", "cp", argv[i], buf);
+                       exit(1);
+               }
+               wait(&stat);
+       }
+       exit(0);
+}
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/cu.c b/usr/src/cmd/cu.c
new file mode 100644 (file)
index 0000000..39ee82c
--- /dev/null
@@ -0,0 +1,539 @@
+#include <stdio.h>
+#include <signal.h>
+#include <sgtty.h>
+/*
+ *     cu telno [-t] [-s speed] [-l line] [-a acu]
+ *
+ *     -t is for dial-out to terminal.
+ *     speeds are: 110, 134, 150, 300, 1200. 300 is default.
+ *
+ *     Escape with `~' at beginning of line.
+ *     Ordinary diversions are ~<, ~> and ~>>.
+ *     Silent output diversions are ~>: and ~>>:.
+ *     Terminate output diversion with ~> alone.
+ *     Quit is ~. and ~! gives local command or shell.
+ *     Also ~$ for canned procedure pumping remote.
+ *     ~%put from [to]  and  ~%take from [to] invoke builtins
+ */
+
+#define CRLF "\r\n"
+#define wrc(ds) write(ds,&c,1)
+
+
+char   *devcul = "/dev/cul0";
+char   *devcua = "/dev/cua0";
+char   *lspeed = "300";
+
+int    ln;     /* fd for comm line */
+char   tkill, terase;  /* current input kill & erase */
+char   c;
+
+char   *connmsg[] = {
+       "",
+       "line busy",
+       "call dropped",
+       "no carrier",
+       "can't fork",
+       "acu access",
+       "tty access",
+       "tty hung",
+       "usage: cu telno [-t] [-s speed] [-l line] [-a acu]"
+};
+
+rdc(ds) {
+
+       ds=read(ds,&c,1); 
+       c&= 0177; 
+       return (ds);
+}
+
+int intr;
+
+sig2()
+{
+       signal(SIGINT, SIG_IGN); 
+       intr = 1;
+}
+
+int set14;
+
+xsleep(n)
+{
+       xalarm(n);
+       pause();
+       xalarm(0);
+}
+
+xalarm(n)
+{
+       set14=n; 
+       alarm(n);
+}
+
+sig14()
+{
+       signal(SIGALRM, sig14); 
+       if (set14) alarm(1);
+}
+
+int    dout;
+int    nhup;
+
+/*
+ *     main: get connection, set speed for line.
+ *     spawn child to invoke rd to read from line, output to fd 1
+ *     main line invokes wr to read tty, write to line
+ */
+main(ac,av)
+char *av[];
+{
+       int fk;
+       int speed;
+       char *telno;
+       struct sgttyb stbuf;
+
+       signal(SIGALRM, sig14);
+       if (ac < 2) {
+               prf(connmsg[8]);
+               exit(8);
+       }
+       telno = av[1];
+       av += 2;
+       ac -= 2;
+       for (; ac > 0; av++) {
+               if (equal(*av, "-t")) {
+                       dout = 1;
+                       --ac;
+                       continue;
+               }
+               if (ac < 2)
+                       break;
+               if (equal(*av, "-s"))
+                       lspeed = *++av;
+               else if (equal(*av, "-l"))
+                       devcul = *++av;
+               else if (equal(*av, "-a"))
+                       devcua = *++av;
+               else
+                       break;
+               ac -= 2;
+       }
+       if (!exists(devcua) || !exists(devcul))
+               exit(9);
+       ln = conn(devcul, devcua, telno);
+       if (ln < 0) {
+               prf("Connect failed: %s",connmsg[-ln]);
+               exit(-ln);
+       }
+       switch(atoi(lspeed)) {
+       case 110:
+               speed = B110;break;
+       case 150:
+               speed = B150;break;
+       default:
+       case 300:
+               speed = B300;break;
+       case 1200:
+               speed = B1200;break;
+       }
+       stbuf.sg_ispeed = speed;
+       stbuf.sg_ospeed = speed;
+       stbuf.sg_flags = EVENP|ODDP;
+       if (!dout)
+               stbuf.sg_flags |= RAW;
+       ioctl(TIOCSETP, ln, &stbuf);
+       ioctl(TIOCEXCL, ln, (struct sgttyb *)NULL);
+       ioctl(TIOCHPCL, ln, (struct sgttyb *)NULL);
+       prf("Connected");
+       if (dout)
+               fk = -1;
+       else
+               fk = fork();
+       nhup = (int)signal(SIGINT, SIG_IGN);
+       if (fk == 0) {
+               rd();
+               prf("\007Lost carrier");
+               exit(3);
+       }
+       mode(1);
+       wr();
+       mode(0);
+       kill(fk, SIGKILL);
+       wait((int *)NULL);
+       stbuf.sg_ispeed = 0;
+       stbuf.sg_ospeed = 0;
+       ioctl(TIOCSETP, ln, &stbuf);
+       prf("Disconnected");
+       exit(0);
+}
+
+/*
+ *     conn: establish dial-out connection.
+ *     Example:  fd = conn("/dev/ttyh","/dev/dn1","4500");
+ *     Returns descriptor open to tty for reading and writing.
+ *     Negative values (-1...-7) denote errors in connmsg.
+ *     Uses alarm and fork/wait; requires sig14 handler.
+ *     Be sure to disconnect tty when done, via HUPCL or stty 0.
+ */
+
+conn(dev,acu,telno)
+char *dev, *acu, *telno;
+{
+       struct sgttyb stbuf;
+       extern errno;
+       char *p, *q, b[30];
+       int er, fk, dn, dh, t;
+       er=0; 
+       fk=(-1);
+       if ((dn=open(acu,1))<0) {
+               er=(errno == 6? 1:5); 
+               goto X;
+       }
+       if ((fk=fork()) == (-1)) {
+               er=4; 
+               goto X;
+       }
+       if (fk == 0) {
+               open(dev,2); 
+               for (;;) pause();
+       }
+       xsleep(2);
+       /*
+        *      copy phone #, assure EON
+        */
+       p=b; 
+       q=telno;
+       while (*p++=(*q++))
+               ;
+       p--;
+       if (*(p-1)!='<') {
+               if (*(p-1)!='-') *p++='-';
+               *p++='<';
+       }
+       t=p-b;
+       xalarm(5*t);
+       t=write(dn,b,t);
+       xalarm(0);
+       if (t<0) {
+               er=2; 
+               goto X;
+       }
+       /* close(dn) */
+       xalarm(40);             /* was 5; sometimes missed carrier */
+       dh = open(dev,2);
+       xalarm(0);
+       if (dh<0) {
+               er=(errno == 4? 3:6); 
+               goto X;
+       }
+       ioctl(TIOCGETP, ln, &stbuf);
+       stbuf.sg_flags &= ~ECHO;
+       xalarm(10);
+       ioctl(TIOCSETP, dh, &stbuf);
+       ioctl(TIOCHPCL, dh, (struct sgttyb *)NULL);
+       xalarm(0);
+X: 
+       if (er) close(dn);
+       if (fk!=(-1)) {
+               kill(fk, SIGKILL);
+               xalarm(10);
+               while ((t=wait((int *)NULL))!=(-1) && t!=fk);
+               xalarm(0);
+       }
+       return (er? -er:dh);
+}
+
+/*
+ *     wr: write to remote: 0 -> line.
+ *     ~.      terminate
+ *     ~<file  send file
+ *     ~!      local login-style shell
+ *     ~!cmd   execute cmd locally
+ *     ~$proc  execute proc locally, send output to line
+ *     ~%cmd   execute builtin cmd (put and take)
+ */
+
+wr()
+{
+       int ds,fk,lcl,x;
+       char *p,b[600];
+       for (;;) {
+               p=b;
+               while (rdc(0) == 1) {
+                       if (p == b) lcl=(c == '~');
+                       if (p == b+1 && b[0] == '~') lcl=(c!='~');
+                       if (c == 0) c=0177;
+                       if (!lcl) {
+                               if (wrc(ln) == 0) {
+                                       prf("line gone"); return;
+                               }
+                       }
+                       if (lcl) {
+                               if (c == 0177) c=tkill;
+                               if (c == '\r' || c == '\n') goto A;
+                               if (!dout) wrc(0);
+                       }
+                       *p++=c;
+                       if (c == terase) {
+                               p=p-2; 
+                               if (p<b) p=b;
+                       }
+                       if (c == tkill || c == 0177 || c == '\r' || c == '\n') p=b;
+               }
+               return;
+A: 
+               if (!dout) echo("");
+               *p=0;
+               switch (b[1]) {
+               case '.':
+               case '\004':
+                       return;
+               case '!':
+               case '$':
+                       fk = fork();
+                       if (fk == 0) {
+                               close(1);
+                               dup(b[1] == '$'? ln:2);
+                               close(ln);
+                               mode(0);
+                               if (!nhup) signal(SIGINT, SIG_DFL);
+                               if (b[2] == 0) execl("/bin/sh","-",0);
+                               else execl("/bin/sh","sh","-c",b+2,0);
+                               prf("Can't execute shell");
+                               exit(~0);
+                       }
+                       if (fk!=(-1)) {
+                               while (wait(&x)!=fk);
+                       }
+                       mode(1);
+                       if (b[1] == '!') echo("!");
+                       else {
+                               if (dout) echo("$");
+                       }
+                       break;
+               case '<':
+                       if (b[2] == 0) break;
+                       if ((ds=open(b+2,0))<0) {
+                               prf("Can't divert %s",b+1); 
+                               break;
+                       }
+                       intr=x=0;
+                       mode(2);
+                       if (!nhup) signal(SIGINT, sig2);
+                       while (!intr && rdc(ds) == 1) {
+                               if (wrc(ln) == 0) {
+                                       x=1; 
+                                       break;
+                               }
+                       }
+                       signal(SIGINT, SIG_IGN);
+                       close(ds);
+                       mode(1);
+                       if (x) return;
+                       if (dout) echo("<");
+                       break;
+               case '%':
+                       dopercen(&b[2]);
+                       break;
+               default:
+                       prf("Use `~~' to start line with `~'");
+               }
+               continue;
+       }
+}
+
+dopercen(line)
+register char *line;
+{
+       char *args[10];
+       register narg, f;
+       int rcount;
+       for (narg = 0; narg < 10;) {
+               while(*line == ' ' || *line == '\t')
+                       line++;
+               if (*line == '\0')
+                       break;
+               args[narg++] = line;
+               while(*line != '\0' && *line != ' ' && *line != '\t')
+                       line++;
+               if (*line == '\0')
+                       break;
+               *line++ = '\0';
+       }
+       if (equal(args[0], "take")) {
+               if (narg < 2) {
+                       prf("usage: ~%%take from [to]");
+                       return;
+               }
+               if (narg < 3)
+                       args[2] = args[1];
+               wrln("echo '~>:'");
+               wrln(args[2]);
+               wrln(";tee /dev/null <");
+               wrln(args[1]);
+               wrln(";echo '~>'\n");
+               return;
+       } else if (equal(args[0], "put")) {
+               if (narg < 2) {
+                       prf("usage: ~%%put from [to]");
+                       return;
+               }
+               if (narg < 3)
+                       args[2] = args[1];
+               if ((f = open(args[1], 0)) < 0) {
+                       prf("cannot open: %s", args[1]);
+                       return;
+               }
+               wrln("stty -echo;cat >");
+               wrln(args[2]);
+               wrln(";stty echo\n");
+               xsleep(5);
+               intr = 0;
+               if (!nhup)
+                       signal(SIGINT, sig2);
+               mode(2);
+               rcount = 0;
+               while(!intr && rdc(f) == 1) {
+                       rcount++;
+                       if (c == tkill || c == terase)
+                               wrln("\\");
+                       if (wrc(ln) != 1) {
+                               xsleep(2);
+                               if (wrc(ln) != 1) {
+                                       prf("character missed");
+                                       intr = 1;
+                                       break;
+                               }
+                       }
+               }
+               signal(SIGINT, SIG_IGN);
+               close(f);
+               if (intr) {
+                       wrln("\n");
+                       prf("stopped after %d bytes", rcount);
+               }
+               wrln("\004");
+               xsleep(5);
+               mode(1);
+               return;
+       }
+       prf("~%%%s unknown\n", args[0]);
+}
+
+equal(s1, s2)
+register char *s1, *s2;
+{
+       while (*s1++ == *s2)
+               if (*s2++ == '\0')
+                       return(1);
+       return(0);
+}
+
+wrln(s)
+register char *s;
+{
+       while (*s)
+               write(ln, s++, 1);
+}
+
+/*
+ *     rd: read from remote: line -> 1
+ *     catch:
+ *     ~>[>][:][file]
+ *     stuff from file...
+ *     ~>      (ends diversion)
+ */
+
+rd()
+{
+       int ds,slnt;
+       char *p,*q,b[600];
+       p=b;
+       ds=(-1);
+       while (rdc(ln) == 1) {
+               if (ds<0) slnt=0;
+               if (!slnt) wrc(1);
+               *p++=c;
+               if (c!='\n') continue;
+               q=p; 
+               p=b;
+               if (b[0]!='~' || b[1]!='>') {
+                       if (*(q-2) == '\r') {
+                               q--; 
+                               *(q-1)=(*q);
+                       }
+                       if (ds>=0) write(ds,b,q-b);
+                       continue;
+               }
+               if (ds>=0) close(ds);
+               if (slnt) {
+                       write(1, b, q - b);
+                       write(1, CRLF, sizeof(CRLF));
+               }
+               if (*(q-2) == '\r') q--;
+               *(q-1)=0;
+               slnt=0;
+               q=b+2;
+               if (*q == '>') q++;
+               if (*q == ':') {
+                       slnt=1; 
+                       q++;
+               }
+               if (*q == 0) {
+                       ds=(-1); 
+                       continue;
+               }
+               if (b[2]!='>' || (ds=open(q,1))<0) ds=creat(q,0644);
+               lseek(ds, (long)0, 2);
+               if (ds<0) prf("Can't divert %s",b+1);
+       }
+}
+
+struct {char lobyte; char hibyte;};
+mode(f)
+{
+       struct sgttyb stbuf;
+       if (dout) return;
+       ioctl(TIOCGETP, 0, &stbuf);
+       tkill = stbuf.sg_kill;
+       terase = stbuf.sg_erase;
+       if (f == 0) {
+               stbuf.sg_flags &= ~RAW;
+               stbuf.sg_flags |= ECHO|CRMOD;
+       }
+       if (f == 1) {
+               stbuf.sg_flags |= RAW;
+               stbuf.sg_flags &= ECHO|CRMOD;
+       }
+       if (f == 2) {
+               stbuf.sg_flags &= ~RAW;
+               stbuf.sg_flags &= ~(ECHO|CRMOD);
+       }
+       ioctl(TIOCSETP, 0, &stbuf);
+}
+
+echo(s)
+char *s;
+{
+       char *p;
+       for (p=s;*p;p++);
+       if (p>s) write(0,s,p-s);
+       write(0,CRLF, sizeof(CRLF));
+}
+
+prf(f, s)
+char *f;
+char *s;
+{
+       fprintf(stderr, f, s);
+       fprintf(stderr, CRLF);
+}
+
+exists(devname)
+char *devname;
+{
+       if (access(devname, 0)==0)
+               return(1);
+       prf("%s does not exist", devname);
+       return(0);
+}
diff --git a/usr/src/cmd/cvtbl.c b/usr/src/cmd/cvtbl.c
new file mode 100644 (file)
index 0000000..edaddbb
--- /dev/null
@@ -0,0 +1,105 @@
+main(argc,argv)
+       char *argv[];
+{
+/* program to convert tables to new format */
+char *col[20], *len[20];
+char s[200], *p;
+char stt[30];
+int i,j,k,m, first;
+extern int cin, cout;
+for(i=0;i<20;i++)
+       col[i]=len[i]=0;
+first=1;
+while (argc>1 || first)
+       {
+       first=0;
+       if (argc>1)
+               {
+               cin = copen(argv[1], 'r');
+               cout = copen(tmpnam(stt), 'w');
+               }
+       if (cin<0)
+               {
+               printf("can't open file %s\n",argv[1]);
+               cexit(1);
+               }
+       while (gets(s))
+               {
+               puts(s);
+               if (!prefix(".TS", s))
+                       continue;
+               gets(s);
+               k=0;
+               for(p=s; *p; p++)
+                       {
+                       if (letter(*p))
+                               {
+                               col[k++]=p;
+                               while (letter(*p))
+                                       p++;
+                               if (digit(*p))
+                                       len[k-1]=p;
+                               while (digit(*p))
+                                       p++;
+                               }
+                       if (*p==0)break;
+                       }
+               for(i=m=0; i<k; i++)
+                       m=max(length(col[i]),m);
+               for(i=0; i<m; i++)
+                       {
+                       for(j=0; j<k; j++)
+                               {
+                               printf("%c ", *(col[j])++);
+                               if (!letter(*(col[j]))) col[j]--;
+                               if (i==0 && len[i])
+                                       {
+                                       p=len[j];
+                                       while (digit(*p))
+                                               putchar(*p++);
+                                       }
+                               }
+                       if (i+1==m)
+                               printf(".");
+                       printf("\n");
+                       }
+               for(i=0;i<20; i++)
+                       col[i]=len[i]=0;
+               }
+       if (argc>1)
+               {
+               printf(-1, s, "mv %s %s", stt, argv[1]);
+               system(s);
+               argc--;
+               argv++;
+               }
+       }
+}
+length(s)
+       char *s;
+{
+int k;
+for(k=0; s[k]; k++)
+       if (!letter(s[k])) break;
+return(k);
+}
+digit(c)
+{
+return(c>='0' && c<= '9');
+}
+letter(c)
+{
+return((c>='a' && c<= 'z') || (c>= 'A' && c<='Z'));
+}
+prefix(small, big)
+       char *small, *big;
+{
+int c;
+while ((c= *small++) == *big++)
+       if (c==0) return(1);
+return(c==0);
+}
+max(a,b)
+{
+return(a>b? a : b);
+}
diff --git a/usr/src/cmd/dcheck.c b/usr/src/cmd/dcheck.c
new file mode 100644 (file)
index 0000000..6c7019b
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * dcheck - check directory consistency
+ */
+#define        NI      16
+#define        NB      10
+#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];
+
+int    fi;
+ino_t  ino;
+char   *ecount;
+int    headpr;
+unsigned       nfiles;
+
+int    nerror;
+daddr_t        bmap();
+long   atol();
+char   *malloc();
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       long n;
+
+       while (--argc) {
+               argv++;
+               if (**argv=='-')
+               switch ((*argv)[1]) {
+
+               case 'i':
+                       for(i=0; i<NB; i++) {
+                               n = atol(argv[1]);
+                               if(n == 0)
+                                       break;
+                               ilist[i] = n;
+                               argv++;
+                               argc--;
+                       }
+                       ilist[i] = 0;
+                       continue;
+
+               default:
+                       printf("Bad flag %c\n", (*argv)[1]);
+                       nerror++;
+               }
+               check(*argv);
+       }
+       return(nerror);
+}
+
+check(file)
+char *file;
+{
+       register i;
+       register j;
+
+       fi = open(file, 0);
+       if(fi < 0) {
+               printf("cannot open %s\n", file);
+               nerror++;
+               return;
+       }
+       headpr = 0;
+       printf("%s:\n", file);
+       sync();
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       nfiles = (sblock.s_isize-2)*INOPB;
+       if (nfiles > 40000) {
+               printf("Only doing 40000 files\n");
+               nfiles = 40000;
+       }
+       ecount = malloc(nfiles+1);
+       if (ecount==NULL) {
+               printf("Not enough core\n");
+               exit(04);
+       }
+       for (i=0; i<=nfiles; i++)
+               ecount[i] = 0;
+       ino = 0;
+       for(i=2;; i+=NI) {
+               if(ino >= nfiles)
+                       break;
+               bread((daddr_t)i, (char *)itab, sizeof(itab));
+               for(j=0; j<INOPB*NI; j++) {
+                       if(ino >= nfiles)
+                               break;
+                       ino++;
+                       pass1(&itab[j]);
+               }
+       }
+       ino = 0;
+       for(i=2;; i+=NI) {
+               if(ino >= nfiles)
+                       break;
+               bread((daddr_t)i, (char *)itab, sizeof(itab));
+               for(j=0; j<INOPB*NI; j++) {
+                       if(ino >= nfiles)
+                               break;
+                       ino++;
+                       pass2(&itab[j]);
+               }
+       }
+       free(ecount);
+}
+
+pass1(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, BSIZE);
+               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(kno > nfiles || kno <= 1) {
+                               printf("%5u bad; %u/%.14s\n", kno, ino, dp->d_name);
+                               nerror++;
+                               continue;
+                       }
+                       for (k=0; ilist[k] != 0; k++)
+                               if (ilist[k]==kno) {
+                                       printf("%5u arg; %u/%.14s\n", kno, ino, dp->d_name);
+                                       nerror++;
+                               }
+                       ecount[kno]++;
+                       if (ecount[kno] == 0)
+                               ecount[kno] = 0377;
+               }
+       }
+}
+
+pass2(ip)
+register struct dinode *ip;
+{
+       register i;
+
+       i = ino;
+       if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
+               return;
+       if (ip->di_nlink==((ecount[i])&0377) && ip->di_nlink!=0)
+               return;
+       if (headpr==0) {
+               printf("     entries  link cnt\n");
+               headpr++;
+       }
+       printf("%u      %d      %d\n", ino,
+           ecount[i]&0377, ip->di_nlink);
+}
+
+bread(bno, buf, cnt)
+daddr_t bno;
+char *buf;
+{
+       register i;
+
+       lseek(fi, bno*BSIZE, 0);
+       if (read(fi, buf, cnt) != cnt) {
+               printf("read error %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) {
+               printf("%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/deroff.c b/usr/src/cmd/deroff.c
new file mode 100644 (file)
index 0000000..e3732c3
--- /dev/null
@@ -0,0 +1,494 @@
+char *xxxvers = "\nDeroff Version 1.02    24 July 1978\n";
+
+
+#include <stdio.h>
+
+/* Deroff command -- strip troff, eqn, and Tbl sequences from
+a file.  Has one flag argument, -w, to cause output one word per line
+rather than in the original format.
+Deroff follows .so and .nx commands, removes contents of macro
+definitions, equations (both .EQ ... .EN and $...$),
+Tbl command sequences, and Troff backslash constructions.
+
+All input is through the C macro; the most recently read character is in c.
+*/
+
+#define C ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
+#define C1 ( (c=getc(infile)) == EOF ? eof() :  c)
+#define SKIP while(C != '\n') 
+
+#define YES 1
+#define NO 0
+
+#define NOCHAR -2
+#define SPECIAL 0
+#define APOS 1
+#define DIGIT 2
+#define LETTER 3
+
+int wordflag = NO;
+int inmacro = NO;
+int intable = NO;
+
+char chars[128];  /* SPECIAL, APOS, DIGIT, or LETTER */
+
+char line[512];
+char *lp;
+
+int c;
+int ldelim     = NOCHAR;
+int rdelim     = NOCHAR;
+
+
+int argc;
+char **argv;
+
+char fname[50];
+FILE *files[15];
+FILE **filesp;
+FILE *infile;
+
+char *calloc();
+
+
+
+main(ac, av)
+int ac;
+char **av;
+{
+register int i;
+register char *p;
+static char onechar[2] = "X";
+FILE *opn();
+
+argc = ac - 1;
+argv = av + 1;
+
+while(argc>0 && argv[0][0]=='-' && argv[0][1]!='\0') 
+       {
+       for(p=argv[0]+1; *p; ++p) switch(*p)
+               {
+               case 'w':
+                       wordflag = YES;
+                       break;
+               default:
+                       onechar[0] = *p;
+                       fatal("Invalid flag %s\n", onechar);
+               }
+       --argc;
+       ++argv;
+       }
+
+if(argc == 0)
+       infile = stdin;
+else   {
+       infile = opn(argv[0]);
+       --argc;
+       ++argv;
+       }
+
+files[0] = infile;
+filesp = &files[0];
+
+for(i='a'; i<='z' ; ++i)
+       chars[i] = LETTER;
+for(i='A'; i<='Z'; ++i)
+       chars[i] = LETTER;
+for(i='0'; i<='9'; ++i)
+       chars[i] = DIGIT;
+chars['\''] = APOS;
+chars['&'] = APOS;
+
+work();
+}
+
+
+
+skeqn()
+{
+while((c = getc(infile)) != rdelim)
+       if(c == EOF)
+               c = eof();
+       else if(c == '"')
+               while( (c = getc(infile)) != '"')
+                       if(c == EOF)
+                               c = eof();
+                       else if(c == '\\')
+                               if((c = getc(infile)) == EOF)
+                                       c = eof();
+return(C);
+}
+
+
+FILE *opn(p)
+register char *p;
+{
+FILE *fd;
+
+if(p[0]=='-' && p[1]=='\0')
+       fd = stdin;
+else if( (fd = fopen(p, "r")) == NULL)
+       fatal("Cannot open file %s\n", p);
+
+return(fd);
+}
+
+
+
+eof()
+{
+if(infile != stdin)
+       fclose(infile);
+if(filesp > files)
+       infile = *--filesp;
+else if(argc > 0)
+       {
+       infile = opn(argv[0]);
+       --argc;
+       ++argv;
+       }
+else
+       exit(0);
+
+return(C);
+}
+
+
+
+getfname()
+{
+register char *p;
+struct chain { struct chain *nextp; char *datap; } *chainblock;
+register struct chain *q;
+static struct chain *namechain = NULL;
+char *copys();
+
+while(C == ' ') ;
+
+for(p = fname ; (*p=c)!= '\n' && c!=' ' && c!='\t' && c!='\\' ; ++p)
+       C;
+*p = '\0';
+while(c != '\n')
+       C;
+
+/* see if this name has already been used */
+
+for(q = namechain ; q; q = q->nextp)
+       if( ! strcmp(fname, q->datap))
+               {
+               fname[0] = '\0';
+               return;
+               }
+
+q = (struct chain *) calloc(1, sizeof(*chainblock));
+q->nextp = namechain;
+q->datap = copys(fname);
+namechain = q;
+}
+
+
+
+
+fatal(s,p)
+char *s, *p;
+{
+fprintf(stderr, "Deroff: ");
+fprintf(stderr, s, p);
+exit(1);
+}
+\f
+work()
+{
+
+for( ;; )
+       {
+       if(C == '.'  ||  c == '\'')
+               comline();
+       else
+               regline(NO);
+       }
+}
+
+
+
+
+regline(macline)
+int macline;
+{
+line[0] = c;
+lp = line;
+for( ; ; )
+       {
+       if(c == '\\')
+               {
+               *lp = ' ';
+               backsl();
+               }
+       if(c == '\n') break;
+       if(intable && c=='T')
+               {
+               *++lp = C;
+               if(c=='{' || c=='}')
+                       {
+                       lp[-1] = ' ';
+                       *lp = C;
+                       }
+               }
+       else    *++lp = C;
+       }
+
+*lp = '\0';
+
+if(line[0] != '\0')
+       if(wordflag)
+               putwords(macline);
+       else if(macline)
+               putmac(line);
+       else
+               puts(line);
+}
+
+
+
+
+putmac(s)
+register char *s;
+{
+register char *t;
+
+while(*s)
+       {
+       while(*s==' ' || *s=='\t')
+               putchar(*s++);
+       for(t = s ; *t!=' ' && *t!='\t' && *t!='\0' ; ++t)
+               ;
+       if(t>s+2 && chars[ s[0] ]==LETTER && chars[ s[1] ]==LETTER)
+               while(s < t)
+                       putchar(*s++);
+       else
+               s = t;
+       }
+putchar('\n');
+}
+
+
+
+putwords(macline)      /* break into words for -w option */
+int macline;
+{
+register char *p, *p1;
+int i, nlet;
+
+
+for(p1 = line ; ;)
+       {
+       /* skip initial specials ampersands and apostrophes */
+       while( chars[*p1] < DIGIT)
+               if(*p1++ == '\0') return;
+       nlet = 0;
+       for(p = p1 ; (i=chars[*p]) != SPECIAL ; ++p)
+               if(i == LETTER) ++nlet;
+
+       if( (!macline && nlet>1)   /* MDM definition of word */
+          || (macline && nlet>2 && chars[ p1[0] ]==LETTER && chars[ p1[1] ]==LETTER) )
+               {
+               /* delete trailing ampersands and apostrophes */
+               while(p[-1]=='\'' || p[-1]=='&')
+                        --p;
+               while(p1 < p) putchar(*p1++);
+               putchar('\n');
+               }
+       else
+               p1 = p;
+       }
+}
+
+\f
+
+comline()
+{
+register int c1, c2;
+
+while(C==' ' || c=='\t')
+       ;
+if( (c1=c) == '\n')
+       return;
+if(c1 == '.')
+       {
+       inmacro = NO;
+       SKIP;
+       return;
+       }
+if( (c2=C) == '\n')
+       return;
+
+if(c1=='E' && c2=='Q' && filesp==files)
+       eqn();
+else if(c1=='T' && (c2=='S' || c2=='C' || c2=='&') && filesp==files)
+       tbl();
+else if(c1=='T' && c2=='E')
+       intable = NO;
+else if(!inmacro && c1=='d' && c2=='e')
+       macro();
+else if(!inmacro && c1=='i' && c2=='g')
+       macro();
+else if(!inmacro && c1=='a' && c2 == 'm')
+       macro();
+else if(c1=='s' && c2=='o')
+       {
+       getfname();
+       if( fname[0] )
+               infile = *++filesp = opn( fname );
+       }
+else if(c1=='n' && c2=='x')
+       {
+       getfname();
+       if(fname[0] == '\0') exit(0);
+       if(infile != stdin)
+               fclose(infile);
+       infile = *filesp = opn(fname);
+       }
+else if(c1=='h' && c2=='w')
+       { SKIP; }
+else
+       {
+       ++inmacro;
+       regline(YES);
+       --inmacro;
+       }
+}
+
+
+
+macro()
+{
+/*
+do { SKIP; }
+       while(C!='.' || C!='.');        /* look for  .EN */
+SKIP;
+inmacro = YES;
+}
+
+
+
+
+tbl()
+{
+while(C != '.');
+SKIP;
+intable = YES;
+}
+
+eqn()
+{
+register int c1, c2;
+
+SKIP;
+
+for( ;;)
+       {
+       if(C == '.'  || c == '\'')
+               {
+               while(C==' ' || c=='\t')
+                       ;
+               if(c=='E' && C=='N')
+                       {
+                       SKIP;
+                       return;
+                       }
+               }
+       else if(c == 'd')       /* look for delim */
+               {
+               if(C=='e' && C=='l')
+                   if( C=='i' && C=='m')
+                       {
+                       while(C1 == ' ');
+                       if((c1=c)=='\n' || (c2=C1)=='\n'
+                           || (c1=='o' && c2=='f' && C1=='f') )
+                               {
+                               ldelim = NOCHAR;
+                               rdelim = NOCHAR;
+                               }
+                       else    {
+                               ldelim = c1;
+                               rdelim = c2;
+                               }
+                       }
+               }
+
+       if(c != '\n')  SKIP;
+       }
+}
+
+\f
+
+backsl()       /* skip over a complete backslash construction */
+{
+int bdelim;
+
+sw:  switch(C)
+       {
+       case '"':
+               SKIP;
+               return;
+       case 's':
+               if(C == '\\') backsl();
+               else    {
+                       while(C>='0' && c<='9') ;
+                       ungetc(c,infile);
+                       c = '0';
+                       }
+               --lp;
+               return;
+
+       case 'f':
+       case 'n':
+       case '*':
+               if(C != '(')
+                       return;
+
+       case '(':
+               if(C != '\n') C;
+               return;
+
+       case '$':
+               C;      /* discard argument number */
+               return;
+
+       case 'b':
+       case 'x':
+       case 'v':
+       case 'h':
+       case 'w':
+       case 'o':
+       case 'l':
+       case 'L':
+               if( (bdelim=C) == '\n')
+                       return;
+               while(C!='\n' && c!=bdelim)
+                       if(c == '\\') backsl();
+               return;
+
+       case '\\':
+               if(inmacro)
+                       goto sw;
+       default:
+               return;
+       }
+}
+
+
+
+
+char *copys(s)
+register char *s;
+{
+register char *t, *t0;
+
+if( (t0 = t = calloc( strlen(s)+1, sizeof(*t) ) ) == NULL)
+       fatal("Cannot allocate memory", (char *) NULL);
+
+while( *t++ = *s++ )
+       ;
+return(t0);
+}
diff --git a/usr/src/cmd/diff3/diff3.c b/usr/src/cmd/diff3/diff3.c
new file mode 100644 (file)
index 0000000..0983b6f
--- /dev/null
@@ -0,0 +1,421 @@
+#include <stdio.h>
+#
+
+/* diff3 - 3-way differential file comparison*/
+
+/* diff3 [-e] d13 d23 f1 f2 f3 
+ *
+ * d13 = diff report on f1 vs f3
+ * d23 = diff report on f2 vs f3
+ * f1, f2, f3 the 3 files
+*/
+
+struct  range {int from,to; };
+       /* from is first in range of changed lines
+        * to is last+1
+        * from=to=line after point of insertion
+       * for added lines
+       */
+struct diff {struct range old, new;};
+
+#define NC 200
+/* de is used to gather editing scripts,
+ * that are later spewed out in reverse order.
+ * its first element must be all zero
+ * the "new" component of de contains line positions
+ * or byte positions depending on when you look(!?)
+*/
+struct diff d13[NC];
+struct diff d23[NC];
+struct diff de[NC];
+char line[256];
+FILE *fp[3];
+int linct[3] = {0,0,0};
+/*     the number of the last-read line in each file
+ *     is kept in cline[0-2]
+*/
+int cline[3];
+/*     the latest known correspondence between line
+ *     numbers of the 3 files is stored in last[1-3]
+*/
+int last[4];
+int eflag;
+int debug  = 0;
+
+main(argc,argv)
+char **argv;
+{
+       register i,m,n;
+       if(*argv[1]=='-') {
+               switch(argv[1][1]) {
+               default:
+                       eflag = 3;
+                       break;
+               case '3':
+                       eflag = 2;
+                       break;
+               case 'x':
+                       eflag = 1;
+               }
+               argv++;
+               argc--;
+       }
+       if(argc<6) {
+               fprintf(stderr,"diff3: arg count\n");
+               exit(1);
+       }
+       m = readin(argv[1],d13);
+       n = readin(argv[2],d23);
+       for(i=0;i<=2;i++)
+               if((fp[i] = fopen(argv[i+3],"r")) == NULL) {
+                       printf("diff3: can't open %s\n",argv[i+3]);
+                       exit(1);
+               }
+       merge(m,n);
+}
+
+/*pick up the line numbers of allcahnges from
+ * one change file
+ * (this puts the numbers in a vector, which is not
+ * strictly necessary, since the vector is processed
+ * in one sequential pass. The vector could be optimized
+ * out of existence)
+*/
+
+readin(name,dd)
+char *name;
+struct diff *dd;
+{
+       register i;
+       int a,b,c,d;
+       char kind;
+       char *p;
+       fp[0] = fopen(name,"r");
+       for(i=0;getchange(fp[0]);i++) {
+               if(i>=NC) {
+                       fprintf(stderr,"diff3: too many changes\n");
+                       exit(0);
+               }
+               p = line;
+               a = b = number(&p);
+               if(*p==',') {
+                       p++;
+                       b = number(&p);
+               }
+               kind = *p++;
+               c = d = number(&p);
+               if(*p==',') {
+                       p++;
+                       d = number(&p);
+               }
+               if(kind=='a')
+                       a++;
+               if(kind=='d')
+                       c++;
+               b++;
+               d++;
+               dd[i].old.from = a;
+               dd[i].old.to = b;
+               dd[i].new.from = c;
+               dd[i].new.to = d;
+       }
+       dd[i].old.from = dd[i-1].old.to;
+       dd[i].new.from = dd[i-1].new.to;
+       fclose(fp[0]);
+       return(i);
+}
+
+number(lc)
+char **lc;
+{
+       register nn;
+       nn = 0;
+       while(digit(**lc))
+               nn = nn*10 + *(*lc)++ - '0';
+       return(nn);
+}
+
+digit(c)
+{
+       return(c>='0'&&c<='9');
+}
+
+getchange(b)
+FILE *b;
+{
+       while(getline(b))
+               if(digit(line[0]))
+                       return(1);
+       return(0);
+}
+
+getline(b)
+FILE *b;
+{
+       register i, c;
+       for(i=0;i<sizeof(line)-1;i++) {
+               c = getc(b);
+               if(c==EOF)
+                       break;
+               line[i] = c;
+               if(c=='\n') {
+                       line[++i] = 0;
+                       return(i);
+               }
+       }
+       return(0);
+}
+
+merge(m1,m2)
+{
+       register struct diff *d1, *d2, *d3;
+       int dup;
+       int j;
+       int t1,t2;
+       d1 = d13;
+       d2 = d23;
+       j = 0;
+       for(;(t1 = d1<d13+m1) | (t2 = d2<d23+m2);) {
+               if(debug) {
+                       printf("%d,%d=%d,%d %d,%d=%d,%d\n",
+                       d1->old.from,d1->old.to,
+                       d1->new.from,d1->new.to,
+                       d2->old.from,d2->old.to,
+                       d2->new.from,d2->new.to);
+               }
+/*                     first file is different from others*/
+               if(!t2||t1&&d1->new.to < d2->new.from) {
+/*                     stuff peculiar to 1st file */
+                       if(eflag==0) {
+                               separate("1");
+                               change(1,&d1->old,0);
+                               keep(2,&d1->old,&d1->new);
+                               change(3,&d1->new,0);
+                       }
+                       d1++;
+                       continue;
+               }
+/*                     second file is different from others*/
+               if(!t1||t2&&d2->new.to < d1->new.from) {
+                       if(eflag==0) {
+                               separate("2");
+                               keep(1,&d2->old,&d2->new);
+                               change(2,&d2->old,0);
+                               change(3,&d2->new,0);
+                       }
+                       d2++;
+                       continue;
+               }
+/*                     merge overlapping changes in first file
+ *                     this happens after extension see below*/
+               if(d1+1<d13+m1 &&
+                  d1->new.to>=d1[1].new.from) {
+                       d1[1].old.from = d1->old.from;
+                       d1[1].new.from = d1->new.from;
+                       d1++;
+                       continue;
+               }
+/*                     merge overlapping changes in second*/
+               if(d2+1<d23+m2 &&
+                  d2->new.to>=d2[1].new.from) {
+                       d2[1].old.from = d2->old.from;
+                       d2[1].new.from = d2->new.from;
+                       d2++;
+                       continue;
+               }
+/*                     stuff peculiar to third file or different in all*/
+               if(d1->new.from==d2->new.from&&
+                  d1->new.to==d2->new.to) {
+                       dup = duplicate(&d1->old,&d2->old);
+/*                             dup=0 means all files differ
+ *                             dup =1 meands files 1&2 identical*/
+                       if(eflag==0) {
+                               separate(dup?"3":"");
+                               change(1,&d1->old,dup);
+                               change(2,&d2->old,0);
+                               d3 = d1->old.to>d1->old.from?d1:d2;
+                               change(3,&d3->new,0);
+                       } else
+                               j = edit(d1,dup,j);
+                       d1++;
+                       d2++;
+                       continue;
+               }
+/*                     overlapping changes from file1 & 2
+ *                     extend changes appropriately to
+ *                     make them coincide*/
+                if(d1->new.from<d2->new.from) {
+                       d2->old.from -= d2->new.from-d1->new.from;
+                       d2->new.from = d1->new.from;
+               }
+               else if(d2->new.from<d1->new.from) {
+                       d1->old.from -= d1->new.from-d2->new.from;
+                       d1->new.from = d2->new.from;
+               }
+               if(d1->new.to >d2->new.to) {
+                       d2->old.to += d1->new.to - d2->new.to;
+                       d2->new.to = d1->new.to;
+               }
+               else if(d2->new.to >d1->new.to) {
+                       d1->old.to += d2->new.to - d1->new.to;
+                       d1->new.to = d2->new.to;
+               }
+       }
+       if(eflag)
+               edscript(j);
+}
+
+separate(s)
+char *s;
+{
+       printf("====%s\n",s);
+}
+
+/*     the range of ines rold.from thru rold.to in file i
+ *     is to be changed. it is to be printed only if
+ *     it does not duplicate something to be printed later
+*/
+change(i,rold,dup)
+struct range *rold;
+{
+       printf("%d:",i);
+       last[i] = rold->to;
+       prange(rold);
+       if(dup)
+               return;
+       if(debug)
+               return;
+       i--;
+       skip(i,rold->from,(char *)0);
+       skip(i,rold->to,"  ");
+}
+
+/*     print the range of line numbers, rold.from  thru rold.to
+ *     as n1,n2 or n1
+*/
+prange(rold)
+struct range *rold;
+{
+       if(rold->to<=rold->from)
+               printf("%da\n",rold->from-1);
+       else {
+               printf("%d",rold->from);
+               if(rold->to > rold->from+1)
+                       printf(",%d",rold->to-1);
+               printf("c\n");
+       }
+}
+
+/*     no difference was reported by diff between file 1(or 2)
+ *     and file 3, and an artificial dummy difference (trange)
+ *     must be ginned up to correspond to the change reported
+ *     in the other file
+*/
+keep(i,rold,rnew)
+struct range *rold, *rnew;
+{
+       register delta;
+       struct range trange;
+       delta = last[3] - last[i];
+       trange.from = rnew->from - delta;
+       trange.to = rnew->to - delta;
+       change(i,&trange,1);
+}
+
+/*     skip to just befor line number from in file i
+ *     if "pr" is nonzero, print all skipped stuff
+ * w   with string pr as a prefix
+*/
+skip(i,from,pr)
+char *pr;
+{
+       register j,n;
+       for(n=0;cline[i]<from-1;n+=j) {
+               if((j=getline(fp[i]))==0)
+                       trouble();
+               if(pr)
+                       printf("%s%s",pr,line);
+               cline[i]++;
+       }
+       return(n);
+}
+
+/*     return 1 or 0 according as the old range
+ *     (in file 1) contains exactly the same data
+ *     as the new range (in file 2)
+*/
+duplicate(r1,r2)
+struct range *r1, *r2;
+{
+       register c,d;
+       register nchar;
+       int nline;
+       if(r1->to-r1->from != r2->to-r2->from)
+               return(0);
+       skip(0,r1->from,(char *)0);
+       skip(1,r2->from,(char *)0);
+       nchar = 0;
+       for(nline=0;nline<r1->to-r1->from;nline++) {
+               do {
+                       c = getc(fp[0]);
+                       d = getc(fp[1]);
+                       if(c== -1||d== -1)
+                               trouble();
+                       nchar++;
+                       if(c!=d) {
+                               repos(nchar);
+                               return;
+                       }
+               } while(c!= '\n');
+       }
+       repos(nchar);
+       return(1);
+}
+
+repos(nchar)
+{
+       register i;
+       for(i=0;i<2;i++) 
+               fseek(fp[i], (long)-nchar, 1);
+}
+
+trouble()
+{
+       fprintf(stderr,"diff3: logic error\n");
+       abort();
+}
+
+/*     collect an editing script for later regurgitation
+*/
+edit(diff,dup,j)
+struct diff *diff;
+{
+       if(((dup+1)&eflag)==0)
+               return(j);
+       j++;
+       de[j].old.from = diff->old.from;
+       de[j].old.to = diff->old.to;
+       de[j].new.from = de[j-1].new.to
+           +skip(2,diff->new.from,(char *)0);
+       de[j].new.to = de[j].new.from
+           +skip(2,diff->new.to,(char *)0);
+       return(j);
+}
+
+/*             regurgitate */
+edscript(n)
+{
+       register j,k;
+       char block[512];
+       for(n=n;n>0;n--) {
+               prange(&de[n].old);
+               fseek(fp[2], (long)de[n].new.from, 0);
+               for(k=de[n].new.to-de[n].new.from;k>0;k-= j) {
+                       j = k>512?512:k;
+                       if(fread(block,1,j,fp[2])!=j)
+                               trouble();
+                       fwrite(block, 1, j, stdout);
+               }
+               printf(".\n");
+       }
+}
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/dpr.c b/usr/src/cmd/dpr.c
new file mode 100644 (file)
index 0000000..ab7b7b9
--- /dev/null
@@ -0,0 +1,267 @@
+#include <signal.h>
+/*
+ *     dpr -- off line print via dataphone daemon to GCOS
+ *             normally invoked through opr
+ */
+
+char   tfname[]        = "/usr/dpd/tfaXXXXX";
+char   cfname[]        = "/usr/dpd/cfaXXXXX";
+char   lfname[]        = "/usr/dpd/lfaXXXXX";
+char   dfname[]        = "/usr/dpd/dfaXXXXX";
+int    nact;
+int    tff;
+int    mailflg;
+char   person[10];
+int    inchar;
+int    maxrec  = 400;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       register char *arg, *remote;
+       int c, f, flag;
+       int out();
+
+       pidfn();
+       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+               signal(SIGHUP, out);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, out);
+       if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+               signal(SIGQUIT, out);
+       remote = "$     remote  **,onl";
+       flag = 0;
+       tff = nfile(tfname);
+       while (argc>1 && (arg = argv[1])[0]=='-') {
+               if (arg[1] && arg[2]) {
+                       remote[12] = arg[1];
+                       remote[13] = arg[2];
+                       remote[14] = 0;
+               } else switch (arg[1]) {
+
+               case '-':
+                       remote[12] = 'r';
+                       remote[13] = '1';
+                       remote[14] = '\0';
+                       break;
+
+               case 'c':
+                       flag = '+';
+                       break;
+
+               case 'r':
+                       flag = '-';
+                       break;
+
+               case 'm':
+                       mailflg = 1;
+                       break;
+               }
+               argc--;
+               argv++;
+       }
+       card('S', "");
+       card('L', "$    sgrade  2");
+       ident();
+       card('L', remote);
+       card('L', "$    select  ken/mh322");
+       card('L', "$    data    i*,ncksum,copy");
+
+       if(argc == 1)
+               copy(0);
+       while(--argc) {
+               arg = *++argv;
+               if(flag == '+')
+                       goto cf;
+               if(*arg == '/' && flag != '-') {
+                       card('F', arg);
+                       nact++;
+                       continue;
+               }
+               if(link(arg, lfname) < 0)
+                       goto cf;
+               card('F', lfname);
+               card('U', lfname);
+               lfname[inchar]++;
+               nact++;
+               goto df;
+
+       cf:
+               f = open(arg, 0);
+               if(f < 0) {
+                       printf("Cannot open %s\n", arg);
+                       continue;
+               }
+               copy(f);
+               close(f);
+
+       df:
+               if(flag == '-') {
+                       f = unlink(arg);
+                       if(f < 0)
+                               printf("Cannot remove %s\n", arg);
+               }
+       }
+
+       card('L', "$    endcopy");
+       card('L', "$    endjob");
+       if(nact) {
+               tfname[inchar]--;
+               f = link(tfname, dfname);
+               if(f < 0) {
+                       printf("Cannot rename %s\n", dfname);
+                       tfname[inchar]++;
+                       out();
+               }
+               unlink(tfname);
+               execl("/etc/dpd", "dpd", 0);
+               dfname[inchar]++;
+       }
+       out();
+}
+
+copy(f)
+int f;
+{
+       int ff, i, nr, nc;
+       static int buf[256];
+
+       card('F', cfname);
+       card('U', cfname);
+       ff = nfile(cfname);
+       nc = 0;
+       nr = 0;
+       while((i = read(f, buf, 512)) > 0) {
+               write(ff, buf, i);
+               nc += i;
+               if(nc >= 512) {
+                       nc -= 512;
+                       nr++;
+                       if(nr > maxrec) {
+                               printf("Copy file is too large\n");
+                               break;
+                       }
+               }
+       }
+       close(ff);
+       nact++;
+}
+
+card(c, s)
+int c;
+char s[];
+{
+       char *p1, *p2;
+       static char buf[512];
+       int col;
+
+       p1 = buf;
+       p2 = s;
+       col = 0;
+       *p1++ = c;
+       while((c = *p2++) != '\0') {
+               *p1++ = c;
+               col++;
+       }
+       *p1++ = '\n';
+       write(tff, buf, col+2);
+}
+
+ident()
+{
+       int c, n;
+       register char *b1p, *pp, *b2p;
+       static char b1[100], b2[100];
+
+       b1p = b1;
+       if(getpw(getuid(), b1p)) {
+               b1p = "pdp::::m0000,m000:";
+       }
+       n = 0;
+       b2p = b2;
+       while(*b2p++ = "$       ident   "[n++]);
+       b2p--;
+       n = 5;
+       while(--n) while(*b1p++ != ':');
+       while((*b2p++ = *b1p++) != ':');
+       b2p[-1] = ',';
+       b1p = b1;
+       pp = person;
+       while((c = *b1p++) != ':') {
+               *b2p++ = c;
+               *pp++ = c;
+       }
+       *b2p++ = 0;
+       *pp++ = 0;
+       card('L', b2);
+       if (mailflg)
+               card('M', person);
+}
+
+pidfn()
+{
+       register i, j, c;
+       int s;
+       int p;
+
+       s = p = getpid();
+       p &= 077777;
+       i = 0;
+       while(tfname[i] != 'X')
+               i++;
+       i += 4;
+       for(j=0; j<5; j++) {
+               c = (p%10) + '0';
+               if(s<0 && j==4)
+                       c += 4;
+               p /= 10;
+               tfname[i] = c;
+               cfname[i] = c;
+               lfname[i] = c;
+               dfname[i] = c;
+               i--;
+       }
+       inchar = i;
+}
+
+nfile(name)
+char *name;
+{
+       register f;
+
+       f = creat(name, 0666);
+       if(f < 0) {
+               printf("Cannot create %s\n", name);
+               out();
+       }
+       name[inchar]++;
+       return(f);
+}
+
+out()
+{
+       register i;
+
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       i = inchar;
+       while(tfname[i] != 'a') {
+               tfname[i]--;
+               unlink(tfname);
+       }
+       while(cfname[i] != 'a') {
+               cfname[i]--;
+               unlink(cfname);
+       }
+       while(lfname[i] != 'a') {
+               lfname[i]--;
+               unlink(lfname);
+       }
+       while(dfname[i] != 'a') {
+               dfname[i]--;
+               unlink(dfname);
+       }
+       exit(0);
+}
diff --git a/usr/src/cmd/draw.c b/usr/src/cmd/draw.c
new file mode 100644 (file)
index 0000000..21727d8
--- /dev/null
@@ -0,0 +1,3 @@
+/*
+see agf for this source
+*/
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/group.c b/usr/src/cmd/group.c
new file mode 100644 (file)
index 0000000..f629967
--- /dev/null
@@ -0,0 +1,12 @@
+#include <grp.h>
+#define        NULL    0
+
+struct group *getgrgid(), *grp;
+
+main()
+{
+       if((grp=getgrgid(getgid())) == NULL) 
+               printf("%d\n", getgid());
+       else
+               printf("%s\n", grp->gr_name);
+}
diff --git a/usr/src/cmd/init.c b/usr/src/cmd/init.c
new file mode 100644 (file)
index 0000000..7ac4a4b
--- /dev/null
@@ -0,0 +1,302 @@
+#include <signal.h>
+#include <sys/types.h>
+#include <utmp.h>
+#include <setjmp.h>
+
+#define        TABSIZ  100
+#define        ALL     p = &itab[0]; p < &itab[TABSIZ]; p++
+#define        EVER    ;;
+
+char   shell[] = "/bin/sh";
+char   getty[]  = "/etc/getty";
+char   minus[] = "-";
+char   runc[]  = "/etc/rc";
+char   ifile[] = "/etc/ttys";
+char   utmp[]  = "/etc/utmp";
+char   wtmpf[] = "/usr/adm/wtmp";
+char   ctty[]  = "/dev/console";
+char   dev[]   = "/dev/";
+
+struct utmp wtmp;
+struct
+{
+       char    line[8];
+       char    comn;
+       char    flag;
+} line;
+struct tab
+{
+       char    line[8];
+       char    comn;
+       int     pid;
+} itab[TABSIZ];
+
+int    fi;
+char   tty[20];
+jmp_buf        sjbuf;
+
+main()
+{
+       int reset();
+
+       setjmp(sjbuf);
+       signal(SIGHUP, reset);
+       for(EVER) {
+               shutdown();
+               single();
+               runcom();
+               merge();
+               multiple();
+       }
+}
+
+shutdown()
+{
+       register i;
+       register struct tab *p;
+
+       signal(SIGINT, SIG_IGN);
+       for(ALL)
+               term(p);
+       signal(SIGALRM, reset);
+       alarm(60);
+       for(i=0; i<5; i++)
+               kill(-1, SIGKILL);
+       while(wait((int *)0) != -1)
+               ;
+       alarm(0);
+       signal(SIGALRM, SIG_DFL);
+       for(i=0; i<10; i++)
+               close(i);
+}
+
+single()
+{
+       register pid;
+
+       pid = fork();
+       if(pid == 0) {
+/*
+               alarm(300);
+*/
+               signal(SIGHUP, SIG_DFL);
+               signal(SIGINT, SIG_DFL);
+               signal(SIGALRM, SIG_DFL);
+               open(ctty, 2);
+               dup(0);
+               dup(0);
+               execl(shell, minus, (char *)0);
+               exit(0);
+       }
+       while(wait((int *)0) != pid)
+               ;
+}
+
+runcom()
+{
+       register pid;
+
+       pid = fork();
+       if(pid == 0) {
+               open("/", 0);
+               dup(0);
+               dup(0);
+               execl(shell, shell, runc, (char *)0);
+               exit(0);
+       }
+       while(wait((int *)0) != pid)
+               ;
+}
+
+multiple()
+{
+       register struct tab *p;
+       register pid;
+
+       for(EVER) {
+               pid = wait((int *)0);
+               if(pid == -1)
+                       return;
+               for(ALL)
+                       if(p->pid == pid || p->pid == -1) {
+                               rmut(p);
+                               dfork(p);
+                       }
+       }
+}
+
+term(p)
+register struct tab *p;
+{
+
+       if(p->pid != 0) {
+               rmut(p);
+               kill(p->pid, SIGKILL);
+       }
+       p->pid = 0;
+       p->line[0] = 0;
+}
+
+rline()
+{
+       register c, i;
+
+       c = get();
+       if(c < 0)
+               return(0);
+       if(c == 0)
+               goto bad;
+       line.flag = c;
+       c = get();
+       if(c <= 0)
+               goto bad;
+       line.comn = c;
+       for(i=0; i<8; i++)
+               line.line[i] = 0;
+       for(i=0; i<7; i++) {
+               c = get();
+               if(c <= 0)
+                       break;
+               line.line[i] = c;
+       }
+       while(c > 0)
+               c = get();
+       maktty(line.line);
+       if(access(tty, 06) < 0)
+               goto bad;
+       return(1);
+
+bad:
+       line.flag = '0';
+       return(1);
+}
+
+maktty(lin)
+char *lin;
+{
+       register i, j;
+
+       for(i=0; dev[i]; i++)
+               tty[i] = dev[i];
+       for(j=0; lin[j]; j++) {
+               tty[i] = lin[j];
+               i++;
+       }
+       tty[i] = 0;
+}
+
+get()
+{
+       char b;
+
+       if(read(fi, &b, 1) != 1)
+               return(-1);
+       if(b == '\n')
+               return(0);
+       return(b);
+}
+
+merge()
+{
+       register struct tab *p, *q;
+       register i;
+
+       close(creat(utmp, 0644));
+       signal(SIGINT, merge);
+       fi = open(ifile, 0);
+       if(fi < 0)
+               return;
+       q = &itab[0];
+       while(rline()) {
+               if(line.flag == '0')
+                       continue;
+               for(ALL) {
+                       if(p->line[0] != 0)
+                       for(i=0; i<8; i++)
+                               if(p->line[i] != line.line[i])
+                                       goto contin;
+                       if(p >= q) {
+                               i = p->pid;
+                               p->pid = q->pid;
+                               q->pid = i;
+                               for(i=0; i<8; i++)
+                                       p->line[i] = q->line[i];
+                               p->comn = q->comn;
+                               for(i=0; i<8; i++)
+                                       q->line[i] = line.line[i];
+                               q->comn = line.comn;
+                               q++;
+                       }
+                       break;
+               contin:
+                       ;
+               }
+       }
+       close(fi);
+       for(; q < &itab[TABSIZ]; q++)
+               term(q);
+       for(ALL)
+               if(p->line[0] != 0 && p->pid == 0)
+                       dfork(p);
+}
+
+dfork(p)
+struct tab *p;
+{
+       register pid;
+
+       pid = fork();
+       if(pid == 0) {
+               signal(SIGHUP, SIG_DFL);
+               signal(SIGINT, SIG_DFL);
+               maktty(p->line);
+               chown(tty, 0, 0);
+               chmod(tty, 0622);
+               open(tty, 2);
+               dup(0);
+               dup(0);
+               tty[0] = p->comn;
+               tty[1] = 0;
+               execl(getty, minus, tty, (char *)0);
+               exit(0);
+       }
+       p->pid = pid;
+}
+
+rmut(p)
+register struct tab *p;
+{
+       register i, f;
+
+       f = open(utmp, 2);
+       if(f >= 0) {
+               while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
+                       for(i=0; i<8; i++)
+                               if(wtmp.ut_line[i] != p->line[i])
+                                       goto contin;
+                       lseek(f, (long)-sizeof(wtmp), 1);
+                       for(i=0; i<8; i++)
+                               wtmp.ut_name[i] = 0;
+                       time(&wtmp.ut_time);
+                       write(f, (char *)&wtmp, sizeof(wtmp));
+               contin:;
+               }
+               close(f);
+       }
+       f = open(wtmpf, 1);
+       if (f >= 0) {
+               for(i=0; i<8; i++) {
+                       wtmp.ut_name[i] = 0;
+                       wtmp.ut_line[i] = p->line[i];
+               }
+               time(&wtmp.ut_time);
+               lseek(f, (long)0, 2);
+               write(f, (char *)&wtmp, sizeof(wtmp));
+               close(f);
+       }
+}
+
+reset()
+{
+       longjmp(sjbuf, 1);
+}
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/line.c b/usr/src/cmd/line.c
new file mode 100644 (file)
index 0000000..baa7695
--- /dev/null
@@ -0,0 +1,14 @@
+main()
+{
+char *ttyname() ;
+register char *tty , *cp ;
+cp  = ttyname(0) ;
+cp++ ;
+while (*cp++ != '/') ;
+tty = cp ;
+while (*cp)cp++ ;
+*++cp = '\n' ;
+*++cp = '\0' ;
+write(1,tty,10) ;
+}
diff --git a/usr/src/cmd/lpd.c b/usr/src/cmd/lpd.c
new file mode 100644 (file)
index 0000000..8ef7088
--- /dev/null
@@ -0,0 +1,180 @@
+#include <signal.h>
+/*
+ * Line-printer daemon for Versatek
+ *
+ */
+
+#define        TIMEOUT 100
+#define        DAEMUID 1
+
+struct {
+       int     ino;
+       char    name[14];
+} dbuf;
+
+char   line[128];
+char   banbuf[64];
+int    linel;
+int    dfb[259];
+char   dfname[26] = "/usr/lpd/";
+int    waittm  = 60;
+
+main(argc, argv)
+{
+       register char *p1, *p2;
+       register df;
+
+       setuid(DAEMUID);
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+/*
+ * Close all files, open root as 0, 1, 2
+ * to assure standard environment
+ */
+       for (df=0; df<=15; df++)
+               close(df);
+       open("/", 0);
+       dup(0);
+       dup(0);
+       if ((df=creat("/usr/lpd/lock", 0)) < 0)
+               exit(0);
+       close(df);
+       if (fork())
+               exit(0);
+again:
+       df = open("/usr/lpd", 0);
+       do {
+               if (read(df, &dbuf, sizeof dbuf) < sizeof dbuf) {
+                       unlink("/usr/lpd/lock");
+                       exit(0);
+               }
+       } while (dbuf.ino==0 || dbuf.name[0]!='d' || dbuf.name[1]!='f');
+       close(df);
+       p1 = dbuf.name;
+       p2 = &dfname[9];
+       while (p1 < &dbuf.name[14])
+               *p2++ = *p1++;
+       if (trysend(dfname) == 0)
+               goto again;
+       sleep(waittm);
+       goto again;
+}
+
+trysend(file)
+{
+       register char *p1, *p2;
+       register i;
+       extern int badexit();
+
+       if (fopen(file, dfb) < 0)
+               return(0);
+       banbuf[0] = 0;
+       while (getline()) switch (line[0]) {
+       case 'L':
+               p1 = line+1;
+               p2 = banbuf;
+               while (*p2++ = *p1++);
+               continue;
+
+       case 'F':
+               if (send())
+                       return(1);
+               continue;
+
+       case 'U':
+               continue;
+
+       case 'M':
+               continue;
+       }
+/*
+ * Second pass.
+ * Unlink files and send mail.
+ */
+       lseek(dfb[0], 0L, 0);
+       dfb[1] = 0;
+       while (getline()) switch (line[0]) {
+
+       default:
+               continue;
+
+       case 'U':
+               unlink(&line[1]);
+               continue;
+
+       case 'M':
+               sendmail();
+               continue;
+       }
+       close(dfb[0]);
+       unlink(file);
+}
+
+sendmail()
+{
+       static int p[2];
+       register i;
+       int stat;
+
+       pipe(p);
+       if (fork()==0) {
+               alarm(0);
+               close(0);
+               dup(p[0]);
+               for (i=3; i<=15; i++)
+                       close(i);
+               execl("/bin/mail", "mail", &line[1], 0);
+               exit(0);
+       }
+       close(1);
+       dup(p[1]);
+       printf("Your printer job is done\n");
+       close(1);
+       close(p[0]);
+       close(p[1]);
+       open("/", 0);
+       wait(&stat);
+}
+
+getline()
+{
+       register char *lp;
+       register c;
+
+       lp = line;
+       linel = 0;
+       while ((c = getc(dfb)) != '\n') {
+               if (c<0)
+                       return(0);
+               if (c=='\t') {
+                       do {
+                               *lp++ = ' ';
+                               linel++;
+                       } while ((linel & 07) != 0);
+                       continue;
+               }
+               *lp++ = c;
+               linel++;
+       }
+       *lp++ = 0;
+       return(1);
+}
+
+send()
+{
+       int p;
+
+       if (p = fork()) {
+               if (p == -1)
+                       return(1);
+               wait(&p);
+               return(p);
+       }
+       if (banbuf[0]) {
+               execl("/usr/bin/vpr", "vpr", "-b", banbuf, line+1, 0);
+               return(1);
+       }
+       execl("/usr/bin/vpr", "vpr", line, 0);
+       return(1);
+}
diff --git a/usr/src/cmd/lpr.c b/usr/src/cmd/lpr.c
new file mode 100644 (file)
index 0000000..fec6ad1
--- /dev/null
@@ -0,0 +1,261 @@
+#include <signal.h>
+/*
+ *     lpr -- on-line printer spooler
+ *             normally invoked through opr
+ */
+
+char   tfname[]        = "/usr/lpd/tfaXXXXX";
+char   cfname[]        = "/usr/lpd/cfaXXXXX";
+char   lfname[]        = "/usr/lpd/lfaXXXXX";
+char   dfname[]        = "/usr/lpd/dfaXXXXX";
+int    nact;
+int    tff;
+int    mailflg;
+char   person[10];
+int    inchar;
+int    maxrec  = 400;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       register char *arg, *remote;
+       int c, f, flag;
+       int out();
+
+       pidfn();
+       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+               signal(SIGHUP, out);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, out);
+       if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+               signal(SIGQUIT, out);
+       remote = "$     remote  **,onl";
+       flag = 0;
+       tff = nfile(tfname);
+       while (argc>1 && (arg = argv[1])[0]=='-') {
+               if (arg[1] && arg[2]) {
+                       remote[12] = arg[1];
+                       remote[13] = arg[2];
+                       remote[14] = 0;
+               } else switch (arg[1]) {
+
+               case '-':
+                       remote[12] = 'r';
+                       remote[13] = '1';
+                       remote[14] = '\0';
+                       break;
+
+               case 'c':
+                       flag = '+';
+                       break;
+
+               case 'r':
+                       flag = '-';
+                       break;
+
+               case 'm':
+                       mailflg = 1;
+                       break;
+               }
+               argc--;
+               argv++;
+       }
+       ident();
+       if(argc == 1)
+               copy(0);
+       while(--argc) {
+               arg = *++argv;
+               if(flag == '+')
+                       goto cf;
+               if(*arg == '/' && flag != '-') {
+                       card('F', arg);
+                       nact++;
+                       continue;
+               }
+               if(link(arg, lfname) < 0)
+                       goto cf;
+               card('F', lfname);
+               card('U', lfname);
+               lfname[inchar]++;
+               nact++;
+               goto df;
+
+       cf:
+               f = open(arg, 0);
+               if(f < 0) {
+                       printf("Cannot open %s\n", arg);
+                       continue;
+               }
+               copy(f);
+               close(f);
+
+       df:
+               if(flag == '-') {
+                       f = unlink(arg);
+                       if(f < 0)
+                               printf("Cannot remove %s\n", arg);
+               }
+       }
+
+       if(nact) {
+               tfname[inchar]--;
+               f = link(tfname, dfname);
+               if(f < 0) {
+                       printf("Cannot rename %s\n", dfname);
+                       tfname[inchar]++;
+                       out();
+               }
+               unlink(tfname);
+               execl("/usr/lib/lpd", "lpd", 0);
+               dfname[inchar]++;
+               printf("Daemon doesn't exist\n");
+               exit(0);
+       }
+       out();
+}
+
+copy(f)
+int f;
+{
+       int ff, i, nr, nc;
+       static int buf[256];
+
+       card('F', cfname);
+       card('U', cfname);
+       ff = nfile(cfname);
+       nc = 0;
+       nr = 0;
+       while((i = read(f, buf, 512)) > 0) {
+               write(ff, buf, i);
+               nc += i;
+               if(nc >= 512) {
+                       nc -= 512;
+                       nr++;
+                       if(nr > maxrec) {
+                               printf("Copy file is too large\n");
+                               break;
+                       }
+               }
+       }
+       close(ff);
+       nact++;
+}
+
+card(c, s)
+int c;
+char s[];
+{
+       char *p1, *p2;
+       static char buf[512];
+       int col;
+
+       p1 = buf;
+       p2 = s;
+       col = 0;
+       *p1++ = c;
+       while((c = *p2++) != '\0') {
+               *p1++ = c;
+               col++;
+       }
+       *p1++ = '\n';
+       write(tff, buf, col+2);
+}
+
+ident()
+{
+       int c, n;
+       register char *b1p, *pp, *b2p;
+       static char b1[100], b2[100];
+
+       b1p = b1;
+       if(getpw(getuid(), b1p)) {
+               b1p = "pdp::::m0000,m000:";
+       }
+       n = 0;
+       b2p = b2;
+       while(*b2p++ = "$       ident   "[n++]);
+       b2p--;
+       n = 5;
+       while(--n) while(*b1p++ != ':');
+       while((*b2p++ = *b1p++) != ':');
+       b2p[-1] = ',';
+       b1p = b1;
+       pp = person;
+       while((c = *b1p++) != ':') {
+               *b2p++ = c;
+               *pp++ = c;
+       }
+       *b2p++ = 0;
+       *pp++ = 0;
+       card('L', person);
+       if (mailflg)
+               card('M', person);
+}
+
+pidfn()
+{
+       register i, j, c;
+       int s;
+       int p;
+
+       s = p = getpid();
+       p &= 077777;
+       i = 0;
+       while(tfname[i] != 'X')
+               i++;
+       i += 4;
+       for(j=0; j<5; j++) {
+               c = (p%10) + '0';
+               if(s<0 && j==4)
+                       c += 4;
+               p /= 10;
+               tfname[i] = c;
+               cfname[i] = c;
+               lfname[i] = c;
+               dfname[i] = c;
+               i--;
+       }
+       inchar = i;
+}
+
+nfile(name)
+char *name;
+{
+       register f;
+
+       f = creat(name, 0666);
+       if(f < 0) {
+               printf("Cannot create %s\n", name);
+               out();
+       }
+       name[inchar]++;
+       return(f);
+}
+
+out()
+{
+       register i;
+
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       i = inchar;
+       while(tfname[i] != 'a') {
+               tfname[i]--;
+               unlink(tfname);
+       }
+       while(cfname[i] != 'a') {
+               cfname[i]--;
+               unlink(cfname);
+       }
+       while(lfname[i] != 'a') {
+               lfname[i]--;
+               unlink(lfname);
+       }
+       while(dfname[i] != 'a') {
+               dfname[i]--;
+               unlink(dfname);
+       }
+       exit(0);
+}
diff --git a/usr/src/cmd/ls.c b/usr/src/cmd/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/mesg.c b/usr/src/cmd/mesg.c
new file mode 100644 (file)
index 0000000..3d55a36
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * mesg -- set current tty to accept or
+ *     forbid write permission.
+ *
+ *     mesg [y] [n]
+ *             y allow messages
+ *             n forbid messages
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+struct stat sbuf;
+
+char *tty;
+char *ttyname();
+
+main(argc, argv)
+char *argv[];
+{
+       int r=0;
+       tty = ttyname(2);
+       if(stat(tty, &sbuf) < 0) error("cannot stat");
+       if(argc < 2) {
+               if(sbuf.st_mode & 02)
+                       fprintf(stderr,"is y\n");
+               else {  r=1;
+                       fprintf(stderr,"is n\n");
+               }
+       } else  switch(*argv[1]) {
+               case 'y':
+                       newmode(0622); break;
+
+               case 'n':
+                       newmode(0600); r=1; break;
+
+               default:
+                       error("usage: mesg [y] [n]");
+               }
+       exit(r);
+}
+
+error(s)
+char *s;
+{
+       fprintf(stderr,"mesg: %s\n",s);
+       exit(-1);
+}
+
+newmode(m)
+{
+       if(chmod(tty,m)<0)
+               error("cannot change mode");
+}
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/mvall.c b/usr/src/cmd/mvall.c
new file mode 100644 (file)
index 0000000..24e6c8f
--- /dev/null
@@ -0,0 +1,64 @@
+# include <sys/param.h>
+# include <stat.h>
+int    status;
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+register i;
+register char *c1, *c2;
+char dirname[100];
+
+if(argc < 3)
+       {
+       prs("arg count\n");
+       exit(1);
+       }
+argc--;
+c1 = dirname;
+c2 = argv[argc];
+while(*c1++ = *c2++);
+c1[-1] = '/';
+c1[0] = '.';
+c1[1] = '\0';
+if(filetype(dirname) !=  S_IFDIR)
+       {
+       prs(dirname);
+       prs(" is not a directory.\n");
+       exit(1);
+       }
+
+for(i=1; i<argc; i++) 
+       {
+       if(filetype(argv[i]) != S_IFREG)
+               {
+               prs(argv[i]);
+               prs(" is not an ordinary file.\n");
+               }
+       else if(fork() == 0)
+               {
+               execl("/bin/mv", "mv", argv[i], dirname,0);
+               exit(1);
+               }
+       else wait(&status);
+       }
+}
+
+filetype(filename)
+char *filename;
+{
+struct stat buf ;
+
+if(stat(filename,&buf) < 0) 
+       return(-1);
+else return(buf.st_mode&S_IFMT);
+}
+
+
+prs(s)
+register char *s;
+{
+while(*s)
+       write(2, s++, 1);
+}
diff --git a/usr/src/cmd/newgrp.c b/usr/src/cmd/newgrp.c
new file mode 100644 (file)
index 0000000..af49a5e
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+
+struct group   *getgrnam(), *grp;
+struct passwd  *getpwuid(), *pwd;
+char   *getpass(), *crypt();
+
+main(argc,argv)
+int    argc;
+char   **argv;
+{
+       register i;
+       if(argc != 2) {
+               printf("usage: newgrp groupname\n");
+               done();
+       }
+       if((grp=getgrnam(argv[1])) == NULL) {
+               printf("%s: no such group\n", argv[1]);
+               done();
+       }
+       if((pwd=getpwuid(getuid())) == NULL) {
+               printf("You do not exist!\n");
+               done();
+       }
+       for(i=0;grp->gr_mem[i];i++) 
+               if(strcmp(grp->gr_mem[i], pwd->pw_name) == 0)
+                       break;
+       if(grp->gr_mem[i] == 0 && strcmp(grp->gr_name,"other")) {
+               printf("Sorry\n");
+               done();
+       }
+
+       if(grp->gr_passwd[0] != '\0' && pwd->pw_passwd[0] == '\0') {
+               if(strcmp(grp->gr_passwd, crypt(getpass("Password:"),grp->gr_passwd)) != 0) {
+                       printf("Sorry\n");
+                       done();
+               }
+       }
+       if(setgid(grp->gr_gid) < 0)
+               perror("setgid");
+       done();
+}
+
+done()
+{
+       register i;
+
+       setuid(getuid());
+       for (i=3; i<15; i++)
+               close(i);
+       execl("/bin/sh", "sh", 0);
+       printf("No shell!\n");
+       exit(0);
+}
diff --git a/usr/src/cmd/number.c b/usr/src/cmd/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;
+}
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/opr.c b/usr/src/cmd/opr.c
new file mode 100644 (file)
index 0000000..a57107a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *     opr -- off line print dispatcher
+ *             chooses spooling routine appropriate 
+ *             to destination
+ *
+ *     last entry in table isdefault
+ */
+
+char *code[] = {
+       "-sp",  "/usr/lib/npr", /* spider network printer */
+       "-lp",  "/usr/bin/lpr", /* line printer */
+       "-mh",  "/usr/lib/dpr", /* GCOS via 201 dataphone */
+       0
+};
+
+main(argc, argv)
+char **argv;
+{
+       int i, j;
+
+       argv[argc] = 0;
+       for(i=0; code[i+2]; i+=2)
+       if(argc > 1)
+               for(j=0; code[i][j]==argv[1][j]; j++)
+                       if(code[i][j] == 0)
+                               goto OK;
+OK:
+       execv(code[i+1]+4, &argv[0]);
+       execv(code[i+1], &argv[0]);
+       write(2, "can't start daemon\n", 19);
+}
diff --git a/usr/src/cmd/paste.c b/usr/src/cmd/paste.c
new file mode 100644 (file)
index 0000000..534add3
--- /dev/null
@@ -0,0 +1,137 @@
+#
+/* paste: concatenate corresponding lines of each file in parallel(GWRL) */
+/*     (-s option: serial concatenation like old (127's) paste command */
+/* make :  cc paste.c -lS */
+# include <stdio.h>
+# define MAXOPNF 12    /* maximal no. of open files (not with -s option) */
+# define MAXLINE 512   /* maximal line length */
+#define RUB  '\177'
+       char del[MAXLINE] = {"\t"};
+  
+main(argc, argv)
+int argc;
+char ** argv;
+{
+       int i, j, k, eofcount, nfiles;
+       int delcount = { 1 } ;
+       int onefile  = { 0 } ;
+       char outbuf[MAXLINE], c, l ;
+       register char *p;
+       FILE *inptr[MAXOPNF];
+  
+       while (argc > 1 && argv[1][0] == '-' && (c = argv[1][1]) != '\0'){
+               switch (c) {
+                       case 's' :  onefile++;
+                               c = argv[1][2];
+                               argv[1]++;
+                               break ;
+                       case 'd' : argv[1] += 2;
+                               if((delcount = move(argv[1], &del[0])) == 0) diag("no delimiters\n",1);;
+                               break;
+                       default :
+                               diag("Usage: paste [-s] [-d<delimiterstring>] file1 file2 ...", 1);
+                               break;
+               }
+               --argc;
+               ++argv;
+       } /* end options */
+       --argc;
+       if ( ! onefile) {       /* not -s option: parallel line merging */
+               for (i = 0; argc >0 && i < MAXOPNF; i++) {
+                       if (argv[i + 1][0] == '-') {
+                               inptr[i] = stdin;
+                       } else inptr[i] = fopen(argv[i + 1], "r");
+                       if (inptr[i] == NULL) {
+                               diag(argv[i + 1], 0);
+                               diag(" : cannot open\n", 1);
+                       }
+               argc--;
+               }
+               if (argc > 0) diag("too many files\n",1);
+               nfiles = i;
+  
+               do {
+                       p = &outbuf[0];
+                       eofcount = 0;
+                       j = k = 0;
+                       for (i = 0; i < nfiles; i++) {
+                               while((c = getc(inptr[i])) != '\n' && c != EOF)   {
+                                       if (++j <= MAXLINE - 2) *p++ = c ;
+                                       else {
+                                       diag("line too long\n",1);
+                                       }
+                               }
+                               if ( (l = del[k]) != RUB) *p++ = l;
+                               k = (k + 1) % delcount;
+                               if( c == EOF) eofcount++;
+                       }
+                       if (l != RUB) *--p = '\n'; else  *p = '\n';
+                       *++p = 0;
+                       if (eofcount < nfiles) fputs(outbuf, stdout);
+               }while (eofcount < nfiles);
+  
+       } else {        /* -s option: serial file pasting (old 127 paste command) */
+               p = &outbuf[0];
+               j = 0;
+               k = 0;
+               for (i = 1; i <= argc; i++) {
+                       if (argv[i][0] == '-') {
+                               inptr[0] = stdin;
+                       } else inptr[0] = fopen(argv[i], "r");
+                       if (inptr[0] == NULL) {
+                               diag(argv[i], 0);
+                               diag(" : cannot open\n", 1);
+                       }
+         
+                       while((c = getc(inptr[0])) != EOF)   {
+                               if(c != '\n') {
+                                       if (++j <= MAXLINE - 2) *p++ = c ;
+                                       else diag("line too long\n",1);
+                               } else {
+                                       l = del[k];
+                                       if (l != RUB) *p++ = l ;
+                                       k = (k + 1) % delcount;
+                                       *p = 0;
+                                       fputs(outbuf, stdout);
+                                       p = &outbuf[0];
+                                       j = 0;
+                               }
+                       }
+               }
+               if (l != '\n') fputs("\n", stdout);
+       }
+}
+diag(s,r)
+char *s;
+int r;
+{
+       write(2, "paste : ", 8);
+       while(*s)write(2,s++,1);
+       if(r != 0) exit(r);
+}
+  
+move(from, to)
+char *from, *to;
+{
+int c, i;
+       i = 0;
+       do {
+               c = *from++;
+               i++;
+               if (c != '\\') *to++ = c;
+               else { c = *from++;
+                       switch (c) {
+                               case '0' : *to++ = RUB;
+                                               break;
+                               case 't' : *to++ = '\t';
+                                               break;
+                               case 'n' : *to++ = '\n';
+                                               break;
+                               default  : *to++ = c;
+                                               break;
+                       }
+               }
+       } while (c) ;
+return(--i);
+}
diff --git a/usr/src/cmd/pcs.c b/usr/src/cmd/pcs.c
new file mode 100644 (file)
index 0000000..b23bee1
--- /dev/null
@@ -0,0 +1,23 @@
+#include <sys/param.h>
+#include <sys/stat.h>
+struct stat buf;
+
+fault(a)
+{      signal(a,fault);
+}
+
+main()
+{
+       int i; char ch;
+       while (read(0,&ch,1)==1) write(1,&ch,1);
+       printf("PID=%d\n",getpid());
+       printf("signals\n");
+       for(i=1;i<NSIG;i++) {
+               printf("%d ",signal(i,1));
+       }
+       printf("\nfiles\n");
+       for(i=0;i<NOFILE;i++) {
+               printf("%c ",(fstat(i,&buf) != -1 ? 't' : '-'));
+       }
+       printf("\n");
+}
diff --git a/usr/src/cmd/pg.c b/usr/src/cmd/pg.c
new file mode 100644 (file)
index 0000000..ce724aa
--- /dev/null
@@ -0,0 +1,159 @@
+#include <stdio.h>
+
+#define NL '\n'
+#define CLEAR 014
+#define HOME 031
+#define BACK 037
+#define BUFMAX 16384
+#define PAGMAX 64
+
+int file;
+int cp, hp;
+int page[PAGMAX];
+int eof;
+
+char buf[BUFMAX];
+int bptr, bnxt, bend;
+
+
+#define incr(a,b) (a++, a&=b-1)
+#define decr(a,b) (a--, a&=b-1)
+
+
+main(argc,argv)
+char *argv[];
+{
+       int n=1;
+       if(argc<2)
+               print();
+       else {
+               while(argv[n]!=-1) {
+                       if((file=open(argv[n],0))>=0) {
+                               print();
+                               close(file);
+                       } else  printf("dk: `%s' cannot open\n",argv[n]);
+                       n++;
+               }
+       }
+}
+
+print()
+{
+       register int nlc;
+       char buf[2];
+
+       hp=0; cp=0;
+       bptr=bnxt=bend=0;
+       putchar(CLEAR);
+       for(;;) {
+               setpage();
+               nlc=0;
+               putchar(BACK);
+               while(nlc<20) {
+                       char c;
+                       c = readchar();
+                       if(eof)
+                               return;
+                       if(c==NL) nlc++;
+                       putchar(c);
+               }
+               while(read(2,buf,1)==1 && buf[0]!=NL) {
+                       switch(buf[0]) {
+                               case '/':
+                               case HOME:
+                                       putchar(CLEAR);
+                                       getpage(0);
+                                       break;
+                               case '-':
+                               case BACK:
+                                       getpage(-1);
+                                       putchar(CLEAR);
+                                       break;
+                               case '!':
+                                       shell(); buf[0]=NL; break;
+                       }
+               }
+       }
+}
+
+
+#include <signal.h>
+#define EOR '\n'
+shell()
+{
+       int rc, status, unixpid;
+       if( (unixpid=fork())==0 ) {
+               close(0); dup(2);
+               execl("/bin/sh", "sh", "-t", 0);
+               exit(255);
+       }
+       else if(unixpid == -1)
+               return(0);
+       else{   signal(SIGINT,SIG_IGN); signal(SIGQUIT,SIG_IGN);
+               while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
+               signal(SIGINT,SIG_DFL); signal(SIGQUIT,SIG_DFL);
+               return(1);
+       }
+}
+
+readchar()
+{
+       register char c;
+       if(bnxt==bend)
+               fillbuf();
+       if(eof)
+               return(-1);
+       c=buf[bnxt];
+       incr(bnxt,BUFMAX);
+       return(c);
+}
+
+fillbuf()
+{
+       register int r;
+       register int len;
+       ensure();
+       if(eof)
+               return;
+       r=read(file,&buf[bend],512);
+       if(r==-1)
+               return;
+       bend += r; bend &= BUFMAX-1;
+       if(r==0)
+               eof++;
+       return;
+}
+
+ensure()
+{
+       for(;;) {
+               if(bptr<=bend)
+                       return(BUFMAX-bend-1);
+               if(bptr-bend>=512)
+                       return(512);
+               losepage();
+       }
+}
+
+losepage()
+{
+       if(hp<cp)
+               bptr=page[incr(hp,PAGMAX)];
+}
+
+setpage()
+{
+       incr(cp,PAGMAX);
+       if(cp==hp)
+               incr(hp,PAGMAX);
+       page[cp]=bnxt;
+}
+
+getpage(i)
+{
+       if(i==0)
+               cp=hp;
+       else    if(cp!=hp)
+                       decr(cp,PAGMAX);
+       bnxt=page[cp];
+}
diff --git a/usr/src/cmd/rc.c b/usr/src/cmd/rc.c
new file mode 100644 (file)
index 0000000..5a72053
--- /dev/null
@@ -0,0 +1,523 @@
+#include <signal.h>
+/* EFL-Ratfor-Fortran command */
+
+char *setsuf(),*copy();
+extern int fin, fout;
+char   ts[4000];
+char   *tsp    = ts;
+char   *av[500];
+char   *rlist[500];
+int    nr      = 0;
+char   *llist[500];
+int    nl      = 0;
+int    nxo     = 0;
+int    bdcount = 0;    /* count block data files generated */
+int    rflag   = 0;    /* Ratfor or EFL ony, no compile */
+int    dflag   = 0;    /* Compile EFL DEBUG statements if set */
+int    tflag   = 0;    /* Trace operation of command if set */
+int    vflag   = 1;    /* Verify files compiled if set */
+int    mflag   = 0;    /* Ratfor macro pre-pass if set */
+int    fflag   = 0;    /* Save Fortran intermediate files if set */
+int    cflag   = 0;    /* Compile only if set */
+int    Uflag   = 0;    /* Add IMPLICIT UNDEFINED to generated fortran */
+int    Cflag   = 0;    /* Copy Ratfor comments if set */
+int    errcnt;
+char   *arg0;
+char   *complr = "/usr/fort/fc1";
+char   *ratfor = "/usr/bin/ratfor";
+char   *ratout = "ratjunk";
+char   *rattmp = "ratjunk.r";
+char   *ratopt = "-1&";
+char   *efl    = "/usr/bin/efl";
+char   *eflout = "efljunk";
+char   *eflopt = "-u         ";
+char   *macro  = "/usr/bin/m4";
+char   *undecl = "implicit undefined /a-z,A-Z/\n";
+
+# define BADOPEN 127
+main(argc, argv)
+char *argv[]; {
+       char *t;
+       int i, j, c;
+       int dexit();
+
+       arg0 = argv[0];
+       for(i=0; ++i < argc; ) {
+               if(*argv[i] == '-')
+                       for(j=1; argv[i][j]; j++) {
+                               switch (argv[i][j]) {
+                               default:
+                                       if(j == 1) goto passa;
+                                       else continue;
+                               case 'm':
+                                       mflag = 1;
+                                       break;
+                               case 't':
+                                       tflag = 1;
+                                       break;
+                               case 'v':
+                                       vflag = 0;
+                                       break;
+                               case 'd':
+                                       eflopt[7] = 'd';
+                                       break;
+                               case 'g':
+                                       eflopt[2] = 'g';
+                                       eflopt[3] = argv[i][j+1];
+                                       rflag = cflag = fflag = 1;
+                                       break;
+                               case 'e':
+                               case 'r':
+                                       rflag = fflag = cflag = 1;
+                                       break;
+                               case 'f':
+                                       fflag = 1;
+                                       break;
+                               case 'c':
+                                       cflag = 1;
+                                       break;
+                               case 'U':
+                                       Uflag = 1;
+                                       break;
+                               case 'C':
+                                       Cflag = 1;
+                                       break;
+                               case '2':
+                                       complr = "/usr/fort/fc2";
+                                       break;
+                               case '6':
+                                       ratopt[1] = '6';
+                                       ratopt[2] = argv[i][j+1];
+                                       rflag = cflag = fflag = 1;
+                                       break;
+                               case '9':
+                                       eflopt[4] = '9';
+                                       break;
+                               case '#':
+                                       eflopt[5] = '#';
+                                       break;
+                               case 'w':
+                                       eflopt[6] = 'w';
+                                       break;
+                               }
+                       }
+               else {
+          passa:
+                       t = argv[i];
+                       switch( getsuf(t) ) {
+
+                               case 'e':
+                                       eflcomp(t);
+                                       break;
+
+                               case 'r':
+                                       ratcomp(t);
+                                       break;
+
+                               case 'f':
+                                       fortcomp(t);
+                                       llenter(setsuf(copy(t),'o'));
+                                       break;
+
+                               default:
+                                       llenter(copy(t));
+                                       break;
+                               }
+               }
+       }
+       if(rflag)
+               dexit(0);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, dexit);
+       if(tflag)
+               printf("errcnt=%d, nl=%d\n", errcnt, nl);
+       if (errcnt==0 & cflag==0 && nl!=0) {
+               i = 0;
+               av[0] = "ld";
+               av[1] = "-x";
+               av[2] = "/lib/fr0.o";
+               j = 3;
+               while(i<nl)
+                       av[j++] = llist[i++];
+               av[j++] = "-lf";
+               av[j++] = "/usr/lib/filib.a";
+               av[j++] = "-l";
+               av[j++] = 0;
+               callsys("/bin/ld", av);
+       }
+       dexit(errcnt);
+}
+
+dexit(n)
+int n;
+{
+       cunlink(ratout);
+       cunlink(rattmp);
+       cunlink(eflout);
+       cunlink("f.tmp1");
+       if(tflag)
+               printf("%s status=%d\n", arg0, n);
+       exit(n);
+}
+
+eflcomp(s) char *s; {
+       nr = 0;
+       if(vflag)
+               printf("%s:\n",s);
+       if( callprep( efl, s, eflout, eflopt, 0, 0 ) == 0 ) {
+               splitup(eflout);
+               dorlist(s);
+               }
+}
+
+
+
+ratcomp(s) char *s; {
+       int i, j, t;
+       nr = 0;
+       if(vflag)
+               printf("%s:\n",s);
+       if (mflag) {
+               if( ( t = callprep( macro, s, rattmp, 0, 0, 0 ) ) < BADOPEN )
+                       t = callprep( ratfor, rattmp, ratout, ratopt, Cflag?"-C":0, 0 );
+       } else
+               t = callprep( ratfor, s, ratout, ratopt, Cflag?"-C":0, 0 );
+       if( t < BADOPEN ) {
+               splitup(ratout);
+               dorlist(s);
+               }
+}
+
+callprep( prep, file, output, opt1, opt2, opt3 )
+char *prep, *file, *output, *opt1, *opt2, *opt3;
+{
+       int t, status, i, j;
+
+       av[0] = prep;
+       j = 1;
+       if (opt1) av[j++] = opt1;
+       if (opt2) av[j++] = opt2;
+       if (opt3) av[j++] = opt3;
+       av[j] = 0;
+       if( tflag ) {
+               printf("%s <%s ", av[0], file);
+               for (i=1; av[i]; i++)
+                       printf("%s ", av[i]);
+               printf("\n");
+       }
+       if( (t=fork())==0 ){
+               close(1);
+               if( (fout=creat(output, 0666)) < 0) {
+                       error( "can't open %s", output );
+                       dexit(BADOPEN);
+                       }
+               close(0);
+               if( (fin=open(file, 0)) < 0) {
+                       error( "can't open %s", file );
+                       dexit(BADOPEN);
+                       }
+               execv(prep, av);
+               error("can't execute %s", prep);
+               dexit(1);
+       }
+       while( t!=wait(&status) );
+       if( (t=(status&0377)) != 0 && t!=14 )
+               dexit(1);
+       t = (status>>8) & 0377;
+       if( tflag )
+               printf("status = %d\n", t);
+       if( t ) ++errcnt;
+       return ( t );
+}
+
+dorlist(s) char *s; {
+
+       int i, j, t;
+       int fstat;
+
+       if( rflag ) return;
+       fstat = 0;
+       for(i=0; i<nr; i++){
+               if( vflag ) printf("   ");
+               if( fortcomp(rlist[i]) )
+                       fstat++;
+               }
+       if( fstat ) {
+               for(i=0; i<nr; i++) {
+                       cunlink( setsuf( rlist[i], 'o' ) );
+                       if( fflag==0 ) cunlink( setsuf( rlist[i], 'f' ) );
+                       }
+               return;
+               }
+       av[0] = "ld";
+       av[1] = "-r";
+       av[2] = "-x";
+       j = 3;
+       for(i=0; i<nr; i++)
+               av[j++] = rlist[i];
+       av[j] = 0;
+       callsys("/bin/ld", av);
+       t = setsuf(copy(s),'o');
+       if( move( "a.out", t) )
+               errcnt++;
+       llenter(t);
+       for(i=0; i<nr; i++) {
+               if( nodup(llist,rlist[i]) )
+                       cunlink(rlist[i]);
+               if( fflag==0 )
+                       cunlink(setsuf(rlist[i],'f'));
+       }
+}
+
+fortcomp(s) char *s; {
+       int t;
+       if( vflag ) printf("%s:\n", s);
+       av[0] = complr;
+       av[1] = s;
+       av[2] = 0;
+       if( callsys(complr, av) )
+               return(++errcnt);
+       av[0] = "as";
+       av[1] = "-";
+       av[2] = "-o";
+       av[3] = setsuf(s, 'o');
+       av[4] = "f.tmp1";
+       av[5] = 0;
+       callsys("/bin/as", av);
+       return(0);
+}
+
+getsuf(s)
+char s[];
+{
+       int c;
+       char t, *os;
+
+       c = 0;
+       os = s;
+       while(t = *s++)
+               if (t=='/')
+                       c = 0;
+               else
+                       c++;
+       s -= 3;
+       if (c<=14 && c>2 && *s++=='.')
+               return(*s);
+       return(0);
+}
+
+char *
+setsuf(s, ch)
+char s[];
+{
+       char *os;
+
+       os = s;
+       while( *s )
+               if( *s++ == '/' )
+                       os = s;
+       s[-1] = ch;
+       return(os);
+}
+
+move(s,t) char *s, *t; {
+       cunlink(t);
+       if(link(s, t) || cunlink(s)) {
+               printf("move failed: %s\n", t);
+               return(1);
+       }
+       return(0);
+}
+
+callsys(f, v)
+char f[], *v[]; {
+       int i, t, status;
+
+       if(tflag){
+               printf("%s ", f);
+               for(i=0; v[i]; i++)
+                       printf("%s ", v[i]);
+               putchar('\n');
+       }
+       if ((t=fork())==0) {
+               execv(f, v);
+               printf("Can't find %s\n", f);
+               dexit(1);
+       } else
+               if (t == -1) {
+                       printf("Try again\n");
+                       return(1);
+               }
+       while(t!=wait(&status));
+       if ((t=(status&0377)) != 0 && t!=14) {
+               if (t!=2)               /* interrupt */
+                       printf("Fatal error in %s\n", f);
+               dexit(1);
+       }
+       t = (status>>8) & 0377;
+       if( tflag )
+               printf("status = %d\n", t);
+       return(t);
+}
+
+char *
+copy(s)
+char s[]; {
+       char *otsp;
+
+       otsp = tsp;
+       while(*tsp++ = *s++);
+       return(otsp);
+}
+
+nodup(l, s)
+char **l, s[]; {
+       char *t, *os, c;
+
+       if (getsuf(s) != 'o')
+               return(1);
+       os = s;
+       while(t = *l++) {
+               s = os;
+               while(c = *s++)
+                       if (c != *t++)
+                               break;
+               if (*t++ == '\0')
+                       return(0);
+       }
+       return(1);
+}
+
+llenter(t) char *t; {
+       if (nodup(llist, t)) {
+               llist[nl++] = t;
+               if (getsuf(t)=='o')
+                       nxo++;
+       }
+}
+
+cunlink(f)
+char *f;
+{
+       if( tflag )
+               printf("unlink %s\n", f);
+       if (f==0)
+               return(0);
+       return(unlink(f));
+}
+
+splitup(file) char *file; {
+       char in[1500], fname[20];
+       int buf[259];
+       int i,fd,mainsw,c;
+       if( (fin=open(file, 0)) < 0)
+               error("can't open %s", file);
+       while( gets(in) ){
+               if( *in == 'c' || *in == 'C' ) continue;
+               mainsw = getname(in, fname);
+               savename(fname);
+               if( (fd = fcreat(fname, buf)) < 0)
+                       error("can't open %s", fname);
+               if(mainsw && Uflag) {
+                       puts(undecl,buf);
+                       puts(in,buf);
+               } else {
+                       puts(in,buf);
+                       if( Uflag )
+                               puts(undecl,buf);
+               }
+               while( ! endcard(in) ){
+                       gets(in);
+                       puts(in,buf);
+               }
+               fflush(buf);
+               close(fd);
+       }
+       close(fin);
+}
+
+gets(s) char *s; {
+       int c;
+       while( (*s++=c=getchar()) != '\n' && c != '\0' );
+       *s = '\0';
+       return(c);
+}
+
+puts(s,b) char *s; int *b; {
+       while( *s )
+               putc(*s++, b);
+}
+
+savename(s) char *s; {
+       rlist[nr++] = copy(s);
+}
+
+getname(s,f) char *s,*f; {
+       int i,j,c;
+   loop:
+       while( *s == ' ' || *s == '\t' )
+               s++;
+       if( compar(s,"subroutine") ){ s += 10; goto bot; }
+       else if( compar( s,"function") ){ s += 8; goto bot; }
+       else if( compar(s,"real") ){ s += 4; goto loop; }
+       else if( compar(s,"integer") ){ s += 7; goto loop; }
+       else if( compar(s,"logical") ){ s += 7; goto loop; }
+       else if( compar(s,"double") ){ s += 6; goto loop; }
+       else if( compar(s,"precision") ){ s += 9; goto loop; }
+       else if( compar(s,"complex") ){ s += 7; goto loop; }
+       else if( compar(s,"*") ){       /* integer *16 */
+               ++s;
+               while( (*s >= '0' && *s <= '9') || *s == ' ' || *s == '\t' )
+                       s++;
+               goto loop;
+       }
+       else if( compar(s,"block") ){
+               s = "BLOCKDATA ";
+               s[9] = (bdcount++) + '0';
+               goto bot;
+       }
+       else {
+               for(i=0; f[i]="MAIN.f"[i]; i++);
+               return(1);
+       }
+   bot:
+       while( *s == ' ' || *s == '\t' )
+               s++;
+       for(i=0; alphanum(s[i]); i++)
+               f[i] = s[i];
+       f[i++] = '.';
+       f[i++] = 'f';
+       f[i++] = '\0';
+       return(0);
+}
+
+compar(s,t) char *s,*t; {
+       while( *t )
+               if( *s++ != *t++ )
+                       return(0);
+       return(1);
+}
+
+alphanum(c) int c; {
+       return( (c>='a' && c<='z')
+               || (c>='A' && c<='Z')
+               || (c>='0' && c<='9') );
+}
+
+endcard(s) char *s; {
+       if( *s==0 )
+               return(1);
+       while( *s==' ' || *s=='\t' )
+               s++;
+       if( *s!='e' || *(s+1)!='n' || *(s+2)!='d' || *(s+3)!='\n' )
+               return(0);
+       return(1);
+}
+
+error(s1, s2){
+       fout = 2;
+       printf(s1,s2);
+       putchar('\n');
+       flush(1);
+       errcnt++;
+}
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/rew.c b/usr/src/cmd/rew.c
new file mode 100644 (file)
index 0000000..8197254
--- /dev/null
@@ -0,0 +1,26 @@
+main(argc,args)
+char **args ;
+{
+register char *tape ;
+int i , j ;
+if (argc > 2) {
+       usage :
+               printf("usage : rew [[m]digit]\n") ;
+               exit(1) ;
+       }
+tape = "/dev/tap0" ;
+if (argc > 1) {
+       j = 0 ;
+       if (args[1][j] == 'm') {
+               tape = "/dev/mt0" ;
+               i = 7 ;
+               j++ ;
+               }
+       else i = 8 ;
+       if (args[1][j] != '\0') tape[i] = args[1][j] ;
+       }
+i = open(tape,0) ;
+read(i,&j,sizeof(j)) ;
+close(i) ;
+}
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/sa.c b/usr/src/cmd/sa.c
new file mode 100644 (file)
index 0000000..e1f2c97
--- /dev/null
@@ -0,0 +1,487 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/acct.h>
+#include <signal.h>
+
+/* interpret command time accounting */
+
+#define        size    1000
+#define        NC      sizeof(acctbuf.ac_comm)
+struct acct acctbuf;
+int    lflg;
+int    cflg;
+int    iflg;
+int    jflg;
+int    nflg;
+int    aflg;
+int    rflg;
+int    oflg;
+int    tflg;
+int    vflg;
+int    uflg;
+int    thres   = 1;
+int    sflg;
+int    bflg;
+int    mflg;
+
+struct user {
+       int     ncomm;
+       int     fill;
+       float   fctime;
+} user[256];
+
+struct tab {
+       char    name[NC];
+       int     count;
+       float   realt;
+       float   cput;
+       float   syst;
+} tab[size];
+
+float  treal;
+float  tcpu;
+float  tsys;
+int    junkp = -1;
+char   *sname;
+float  ncom;
+time_t expand();
+
+main(argc, argv)
+char **argv;
+{
+       FILE *ff;
+       int i, j, k;
+       extern tcmp(), ncmp(), bcmp();
+       extern float sum();
+       float ft;
+
+       if (argc>1)
+       if (argv[1][0]=='-') {
+               argv++;
+               argc--;
+               for(i=1; argv[0][i]; i++)
+               switch(argv[0][i]) {
+
+               case 'o':
+                       oflg++;
+                       break;
+
+               case 'i':
+                       iflg++;
+                       break;
+
+               case 'b':
+                       bflg++;
+                       break;
+
+               case 'l':
+                       lflg++;
+                       break;
+
+               case 'c':
+                       cflg++;
+                       break;
+
+               case 'j':
+                       jflg++;
+                       break;
+
+               case 'n':
+                       nflg++;
+                       break;
+
+               case 'a':
+                       aflg++;
+                       break;
+
+               case 'r':
+                       rflg++;
+                       break;
+
+               case 't':
+                       tflg++;
+                       break;
+
+               case 's':
+                       sflg++;
+                       aflg++;
+                       break;
+
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                       thres = argv[0][i]-'0';
+                       break;
+
+               case 'v':
+                       vflg++;
+                       break;
+
+               case 'u':
+                       uflg++;
+                       break;
+
+               case 'm':
+                       mflg++;
+                       break;
+               }
+       }
+       if (iflg==0)
+               init();
+       if (argc<2)
+               doacct("/usr/adm/acct");
+       else while (--argc)
+               doacct(*++argv);
+       if (uflg) {
+               return;
+       }
+
+/*
+ * cleanup pass
+ * put junk together
+ */
+
+       if (vflg)
+               strip();
+       if(!aflg)
+       for (i=0; i<size; i++)
+       if (tab[i].name[0]) {
+               for(j=0; j<NC; j++)
+                       if(tab[i].name[j] == '?')
+                               goto yes;
+               if(tab[i].count != 1)
+                       continue;
+       yes:
+               if(junkp == -1)
+                       junkp = enter("***other");
+               tab[junkp].count += tab[i].count;
+               tab[junkp].realt += tab[i].realt;
+               tab[junkp].cput += tab[i].cput;
+               tab[junkp].syst += tab[i].syst;
+               tab[i].name[0] = 0;
+       }
+       for(i=k=0; i<size; i++)
+       if(tab[i].name[0]) {
+               for(j=0; j<NC; j++)
+                       tab[k].name[j] = tab[i].name[j];
+               tab[k].count = tab[i].count;
+               tab[k].realt = tab[i].realt;
+               tab[k].cput = tab[i].cput;
+               tab[k].syst = tab[i].syst;
+               k++;
+       }
+       if (sflg) {
+               signal(SIGINT, SIG_IGN);
+               if ((ff = fopen("/usr/adm/usracct", "w")) != NULL) {
+                       fwrite((char *)user, sizeof(user), 1, ff);
+                       fclose(ff);
+               }
+               if ((ff = fopen("/usr/adm/savacct", "w")) == NULL) {
+                       printf("Can't save\n");
+                       exit(0);
+               }
+               fwrite((char *)tab, sizeof(tab[0]), k, ff);
+               fclose(ff);
+               signal(SIGINT, SIG_DFL);
+       }
+/*
+ * sort and print
+ */
+
+       if (mflg) {
+               printmoney();
+               exit(0);
+       }
+       qsort(tab, k, sizeof(tab[0]), nflg? ncmp: (bflg?bcmp:tcmp));
+       column(ncom, treal, tcpu, tsys);
+       printf("\n");
+       for (i=0; i<k; i++)
+       if (tab[i].name[0]) {
+               ft = tab[i].count;
+               column(ft, tab[i].realt, tab[i].cput, tab[i].syst);
+               printf("   %.14s\n", tab[i].name);
+       }
+}
+
+printmoney()
+{
+       register i;
+       char buf[128];
+       register char *cp;
+
+       for (i=0; i<256; i++) {
+               if (user[i].ncomm) {
+                       if (getpw(i, buf)!=0)
+                               printf("%-8d", i);
+                       else {
+                               cp = buf;
+                               while (*cp!=':' &&*cp!='\n' && *cp)
+                                       cp++;
+                               *cp = 0;
+                               printf("%-8s", buf);
+                       }
+                       printf("%5u %7.2f\n",
+                           user[i].ncomm, user[i].fctime/60);
+               }
+       }
+}
+
+column(n, a, b, c)
+double n, a, b, c;
+{
+
+       printf("%6.0f", n);
+       if(cflg) {
+               if(n == ncom)
+                       printf("%7s", ""); else
+                       printf("%6.2f%%", 100.*n/ncom);
+       }
+       col(n, a, treal);
+       if (oflg)
+               col(n, 3600*(b/(b+c)), tcpu+tsys);
+       else if(lflg) {
+               col(n, b, tcpu);
+               col(n, c, tsys);
+       } else
+               col(n, b+c, tcpu+tsys);
+       if(tflg)
+               printf("%6.1f", a/(b+c));
+}
+
+col(n, a, m)
+double n, a, m;
+{
+
+       if(jflg)
+               printf("%9.2f", a/(n*60.)); else
+               printf("%9.2f", a/3600.);
+       if(cflg) {
+               if(a == m)
+                       printf("%7s", ""); else
+                       printf("%6.2f%%", 100.*a/m);
+       }
+}
+
+doacct(f)
+char *f;
+{
+       int i;
+       FILE *ff;
+       long x;
+       struct acct fbuf;
+       register char *cp;
+       register int c;
+
+       if (sflg && sname) {
+               printf("Only 1 file with -s\n");
+               exit(0);
+       }
+       if (sflg)
+               sname = f;
+       if ((ff = fopen(f, "r"))==NULL) {
+               printf("Can't open %s\n", f);
+               return;
+       }
+       while (fread((char *)&fbuf, sizeof(fbuf), 1, ff) == 1) {
+               if (fbuf.ac_comm[0]==0) {
+                       fbuf.ac_comm[0] = '?';
+               }
+               for (cp = fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++) {
+                       c = *cp & 0377;
+                       if (c && (c < ' ' || c >= 0200)) {
+                               *cp = '?';
+                       }
+               }
+               if (fbuf.ac_flag&AFORK) {
+                       for (cp=fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++)
+                               if (*cp==0) {
+                                       *cp = '*';
+                                       break;
+                               }
+               }
+               x = expand(fbuf.ac_utime) + expand(fbuf.ac_stime);
+               if (uflg) {
+                       printf("%3d%6.1f %.14s\n", fbuf.ac_uid&0377, x/60.0,
+                          fbuf.ac_comm);
+                       continue;
+               }
+               c = fbuf.ac_uid&0377;
+               user[c].ncomm++;
+               user[c].fctime += x/60.;
+               ncom += 1.0;
+               i = enter(fbuf.ac_comm);
+               tab[i].count++;
+               x = expand(fbuf.ac_etime)*60;
+               tab[i].realt += x;
+               treal += x;
+               x = expand(fbuf.ac_utime);
+               tab[i].cput += x;
+               tcpu += x;
+               x = expand(fbuf.ac_stime);
+               tab[i].syst += x;
+               tsys += x;
+       }
+       fclose(ff);
+}
+
+ncmp(p1, p2)
+struct tab *p1, *p2;
+{
+
+       if(p1->count == p2->count)
+               return(tcmp(p1, p2));
+       if(rflg)
+               return(p1->count - p2->count);
+       return(p2->count - p1->count);
+}
+
+bcmp(p1, p2)
+struct tab *p1, *p2;
+{
+       float f1, f2;
+       float sum();
+
+       f1 = sum(p1)/p1->count;
+       f2 = sum(p2)/p2->count;
+       if(f1 < f2) {
+               if(rflg)
+                       return(-1);
+               return(1);
+       }
+       if(f1 > f2) {
+               if(rflg)
+                       return(1);
+               return(-1);
+       }
+       return(0);
+}
+tcmp(p1, p2)
+struct tab *p1, *p2;
+{
+       extern float sum();
+       float f1, f2;
+
+       f1 = sum(p1);
+       f2 = sum(p2);
+       if(f1 < f2) {
+               if(rflg)
+                       return(-1);
+               return(1);
+       }
+       if(f1 > f2) {
+               if(rflg)
+                       return(1);
+               return(-1);
+       }
+       return(0);
+}
+
+float sum(p)
+struct tab *p;
+{
+
+       if(p->name[0] == 0)
+               return(0.0);
+       return(
+               p->cput+
+               p->syst);
+}
+
+init()
+{
+       struct tab tbuf;
+       int i;
+       FILE *f;
+
+       if ((f = fopen("/usr/adm/savacct", "r")) == NULL)
+               goto gshm;
+       while (fread((char *)&tbuf, sizeof(tbuf), 1, f) == 1) {
+               i = enter(tbuf.name);
+               ncom += tbuf.count;
+               tab[i].count = tbuf.count;
+               treal += tbuf.realt;
+               tab[i].realt = tbuf.realt;
+               tcpu += tbuf.cput;
+               tab[i].cput = tbuf.cput;
+               tsys += tbuf.syst;
+               tab[i].syst = tbuf.syst;
+       }
+       fclose(f);
+ gshm:
+       if ((f = fopen("/usr/adm/usracct", "r")) == NULL)
+               return;
+       fread((char *)user, sizeof(user), 1, f);
+       fclose(f);
+}
+
+enter(np)
+char *np;
+{
+       int i, j;
+
+       for (i=j=0; i<NC; i++) {
+               if (np[i]==0)
+                       j = i;
+               if (j)
+                       np[i] = 0;
+       }
+       for (i=j=0; j<NC; j++) {
+               i = i*7 + np[j];
+       }
+       if (i < 0)
+               i = -i;
+       for (i%=size; tab[i].name[0]; i = (i+1)%size) {
+               for (j=0; j<NC; j++)
+                       if (tab[i].name[j]!=np[j])
+                               goto no;
+               goto yes;
+       no:;
+       }
+       for (j=0; j<NC; j++)
+               tab[i].name[j] = np[j];
+yes:
+       return(i);
+}
+
+strip()
+{
+       int i, j, c;
+
+       j = enter("**junk**");
+       for (i = 0; i<size; i++) {
+               if (tab[i].name[0] && tab[i].count<=thres) {
+                       printf("%.14s--", tab[i].name);
+                       if ((c=getchar())=='y') {
+                               tab[i].name[0] = '\0';
+                               tab[j].count += tab[i].count;
+                               tab[j].realt += tab[i].realt;
+                               tab[j].cput += tab[i].cput;
+                               tab[j].syst += tab[i].syst;
+                       }
+                       while (c && c!='\n')
+                               c = getchar();
+               }
+       }
+}
+
+time_t
+expand(t)
+unsigned t;
+{
+       register time_t nt;
+
+       nt = t&017777;
+       t >>= 13;
+       while (t!=0) {
+               t--;
+               nt <<= 3;
+       }
+       return(nt);
+}
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/sp.c b/usr/src/cmd/sp.c
new file mode 100644 (file)
index 0000000..a88ac1f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Print horizontally as possible, thus saving paper
+ */
+#include <stdio.h>
+int tab[8] = {8,7,6,5,4,3,2,1};
+int next;      /*next output position on line*/
+int slen;      /*length at start of line*/
+int alen;      /*actual length*/
+int elen;      /*length on current line*/
+char buf[256];
+getit()
+{      register int i;
+       register c;
+       slen=alen=elen=0;
+       for(i=0;;i++)
+       {       buf[i]=c=getchar();
+               switch(c)
+               {
+               case '\n':      if(i==0) continue;
+               case EOF:
+                       alen=i;
+                       return(i);
+               case '\t':
+                       elen+= tab[(next+elen)%8];
+                       slen += tab[slen%8];
+                       continue;
+               default:
+                       elen++;
+                       slen++;
+                       continue;
+               }
+       }
+}
+putit(ntab)
+{      register int i;
+       for(i=0;i<ntab;i++) putchar('\t');
+       for(i=0;i<alen;i++) putchar(buf[i]);
+}
+clean()
+{
+       putchar('\n');
+}
+main(argc,argv) char *argv[];
+{      int len,ntab;
+       int i;
+       len=80;
+       if(argc>1)
+       {       i=atoi(argv[1]);
+               if(i<0) i= -i;
+               len=(i<1?1:i);
+       }
+       else len=80;
+       for(;;)
+       {       if(next==0) ntab=0;
+               else if(tab[next%8]<1)
+                       {       ntab=2;
+                               next+= tab[next%8];
+                               next += tab[next%8];
+                       }
+                       else
+                       {       ntab=1;
+                               next += tab[next%8];
+                       }
+               if(getit()<=0) {clean(); exit(0);}
+               if(elen+next>=len)
+               {       clean();
+                       next=slen;
+                       putit(0);
+               }
+               else
+               {       next += elen;
+                       putit(ntab);
+               }
+       }
+}
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/tabs4.sh b/usr/src/cmd/tabs4.sh
new file mode 100755 (executable)
index 0000000..8296947
--- /dev/null
@@ -0,0 +1,3 @@
+cat /usr/pub/tabclr
+cat /usr/pub/marg8
+cat /usr/pub/tabs4
diff --git a/usr/src/cmd/tabs8.sh b/usr/src/cmd/tabs8.sh
new file mode 100755 (executable)
index 0000000..476aa53
--- /dev/null
@@ -0,0 +1,2 @@
+cat /usr/pub/tabclr
+cat /usr/pub/tabs
diff --git a/usr/src/cmd/tail.c b/usr/src/cmd/tail.c
new file mode 100644 (file)
index 0000000..b5e5aa9
--- /dev/null
@@ -0,0 +1,163 @@
+/* tail command 
+ *
+ *     tail where [file]
+ *     where is +\b_n[type]
+ *     - means n lines before end
+ *     + means nth line from beginning
+ *     type 'b' means tail n blocks, not lines
+ *     type 'c' means tail n characters
+*/
+#include       <sys/types.h>
+#include       <sys/stat.h>
+#include       <errno.h>
+#define LBIN 4097
+struct stat    statb;
+char bin[LBIN];
+int errno;
+
+main(argc,argv)
+char **argv;
+{
+       long n,di;
+       int fromend;
+       register i,j,k;
+       char *p;
+       int partial,piped,bylines;
+       char *arg;
+       lseek(0,(long)0,1);
+       piped = errno==ESPIPE;
+       arg = argv[1];
+       if(argc<=1 || *arg!='-'&&*arg!='+') {
+               arg = "-10l";
+               argc++;
+               argv--;
+       }
+       fromend = *arg=='-';
+       arg++;
+       if(!digit(*arg))
+               goto errcom;
+       n = 0;
+       while(digit(*arg))
+               n = n*10 + *arg++ - '0';
+       if(!fromend&&n>0)
+               n--;
+       if(argc>2) {
+               close(0);
+               if(open(argv[2],0)!=0) {
+                       write(2,"tail: can't open ",17);
+                       write(2,argv[2],strlen(argv[2]));
+                       write(2,"\n",1);
+                       exit(1);
+               }
+       }
+       bylines = 0;
+       switch(*arg) {
+       case 'b':
+               n <<= 9;
+               break;
+       case 'c':
+               break;
+       case '\0':
+       case 'l':
+               bylines = 1;
+               break;
+       default:
+               goto errcom;
+       }
+       if(fromend)
+               goto keep;
+
+                       /*seek from beginning */
+
+       if(bylines) {
+               j = 0;
+               while(n-->0) {
+                       do {
+                               if(j--<=0) {
+                                       p = bin;
+                                       j = read(0,p,512);
+                                       if(j--<=0) exit(0);
+                               }
+                       } while(*p++ != '\n');
+               }
+               write(1,p,j);
+       } else  if(n>0) {
+               if(!piped)
+                       fstat(0,&statb);
+               if(piped||(statb.st_mode&S_IFMT)==S_IFCHR)
+                       while(n>0) {
+                               i = n>512?512:n;
+                               i = read(0,bin,i);
+                               if(i<=0) exit(0);
+                               n -= i;
+                       }
+               else
+                       lseek(0,n,0);
+       }
+       while((i=read(0,bin,512))>0)
+               write(1,bin,i);
+       exit(0);
+
+                       /*seek from end*/
+
+keep:
+       if(n<=0) exit(0);
+       if(!piped) {
+               fstat(0,&statb);
+               di = !bylines&&n<LBIN?n:LBIN-1;
+               if(statb.st_size > di)
+                       lseek(0,-di,2);
+       }
+       partial = 1;
+       for(;;) {
+               i = 0;
+               do {
+                       j = read(0,&bin[i],LBIN-i);
+                       if(j<=0)
+                               goto brka;
+                       i += j;
+               } while(i<LBIN);
+               partial = 0;
+       }
+brka:
+       if(!bylines) {
+               k =
+                   n<=i ? i-n:
+                   partial ? 0:
+                   n>=LBIN ? i+1:
+                   i-n+LBIN;
+               k--;
+       } else {
+               k = i;
+               j = 0;
+               do {
+                       do {
+                               if(--k<0) {
+                                       if(partial)
+                                               goto brkb;
+                                       k = LBIN -1;
+                               }
+                       } while(bin[k]!='\n'&&k!=i);
+               } while(j++<n&&k!=i);
+brkb:
+               if(k==i) do {
+                       if(++k>=LBIN)
+                               k = 0;
+               } while(bin[k]!='\n'&&k!=i);
+       }
+       if(k<i)
+               write(1,&bin[k+1],i-k-1);
+       else {
+               write(1,&bin[k+1],LBIN-k-1);
+               write(1,bin,i);
+       }
+       exit(0);
+errcom:
+       write(2,"usage: tail +\b_n[lbc] [file]\n",29);
+       exit(1);
+}
+
+digit(c)
+{
+       return(c>='0'&&c<='9');
+}
diff --git a/usr/src/cmd/tee.c b/usr/src/cmd/tee.c
new file mode 100644 (file)
index 0000000..6050d31
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * tee-- pipe fitting
+ */
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+int openf[20] = { 1 };
+int n = 1;
+int t = 0;
+int aflag;
+
+char in[512];
+
+char out[512];
+
+extern errno;
+long   lseek();
+
+main(argc,argv)
+char **argv;
+{
+       int register r,w,p;
+       struct stat buf;
+       while(argc>1&&argv[1][0]=='-') {
+               switch(argv[1][1]) {
+               case 'a':
+                       aflag++;
+                       break;
+               case 'i':
+               case 0:
+                       signal(SIGINT, SIG_IGN);
+               }
+               argv++;
+               argc--;
+       }
+       fstat(1,&buf);
+       t = (buf.st_mode&S_IFMT)==S_IFCHR;
+       if(lseek(1,0L,1)==-1&&errno==ESPIPE)
+               t++;
+       while(argc-->1) {
+               if(aflag) {
+                       openf[n] = open(argv[1],1);
+                       if(openf[n] < 0)
+                               openf[n] = creat(argv[1],0666);
+                       lseek(openf[n++],0L,2);
+               } else
+                       openf[n++] = creat(argv[1],0666);
+               if(stat(argv[1],&buf)>=0) {
+                       if((buf.st_mode&S_IFMT)==S_IFCHR)
+                               t++;
+               } else {
+                       puts("tee: cannot open ");
+                       puts(argv[1]);
+                       puts("\n");
+                       n--;
+               }
+               argv++;
+       }
+       r = w = 0;
+       for(;;) {
+               for(p=0;p<512;) {
+                       if(r>=w) {
+                               if(t>0&&p>0) break;
+                               w = read(0,in,512);
+                               r = 0;
+                               if(w<=0) {
+                                       stash(p);
+                                       return;
+                               }
+                       }
+                       out[p++] = in[r++];
+               }
+               stash(p);
+       }
+}
+
+stash(p)
+{
+       int k;
+       int i;
+       int d;
+       d = t ? 16 : p;
+       for(i=0; i<p; i+=d)
+               for(k=0;k<n;k++)
+                       write(openf[k], out+i, d<p-i?d:p-i);
+}
+
+puts(s)
+char *s;
+{
+       while(*s)
+               write(2,s++,1);
+}
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/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/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/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/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/und.c b/usr/src/cmd/und.c
new file mode 100644 (file)
index 0000000..e562d5b
--- /dev/null
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+main(argc, argv)
+char **argv;
+{
+       register bflg, c, n;
+       int undc=8;
+
+       bflg = 1;
+       if (argc>1 && argv[1][0]=='-') {
+               undc = atoi(&argv[1][1]);
+               if (undc>16)
+                       undc = 0;
+               argc--;
+               argv++;
+       }
+       if (argc>1) {
+               if ((freopen(argv[1], "r", stdin))==NULL) {
+                       fprintf(stderr, "Cannot open %s\n", argv[1]);
+                       exit(1);
+               }
+       }
+       while((c = getchar()) != EOF) {
+               if(c == '\n' || c == 014) {
+                       bflg = 1;
+                       putchar(c);
+                       continue;
+               }
+               if(bflg) {
+                       for (n=0; n<undc; n++)
+                               putchar('\b');
+                       bflg = 0;
+               }
+               putchar(c);
+       }
+       return(0);
+}
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/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/write.c b/usr/src/cmd/write.c
new file mode 100644 (file)
index 0000000..b896a7c
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * write to another user
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <utmp.h>
+
+char   *strcat();
+char   *strcpy();
+struct utmp ubuf;
+int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
+char   me[10]  = "???";
+char   *him;
+char   *mytty;
+char   histty[32];
+char   *histtya;
+char   *ttyname();
+char   *rindex();
+int    logcnt;
+int    eof();
+int    timout();
+FILE   *tf;
+
+main(argc, argv)
+char *argv[];
+{
+       struct stat stbuf;
+       register i;
+       register FILE *uf;
+       int c1, c2;
+
+       if(argc < 2) {
+               printf("usage: write user [ttyname]\n");
+               exit(1);
+       }
+       him = argv[1];
+       if(argc > 2)
+               histtya = argv[2];
+       if ((uf = fopen("/etc/utmp", "r")) == NULL) {
+               printf("cannot open /etc/utmp\n");
+               goto cont;
+       }
+       mytty = ttyname(2);
+       if (mytty == NULL) {
+               printf("Can't find your tty\n");
+               exit(1);
+       }
+       mytty = rindex(mytty, '/') + 1;
+       if (histtya) {
+               strcpy(histty, "/dev/");
+               strcat(histty, histtya);
+       }
+       while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) {
+               if (strcmp(ubuf.ut_line, mytty)==0) {
+                       for(i=0; i<8; i++) {
+                               c1 = ubuf.ut_name[i];
+                               if(c1 == ' ')
+                                       c1 = 0;
+                               me[i] = c1;
+                               if(c1 == 0)
+                                       break;
+                       }
+               }
+               if(him[0] != '-' || him[1] != 0)
+               for(i=0; i<8; i++) {
+                       c1 = him[i];
+                       c2 = ubuf.ut_name[i];
+                       if(c1 == 0)
+                               if(c2 == 0 || c2 == ' ')
+                                       break;
+                       if(c1 != c2)
+                               goto nomat;
+               }
+               logcnt++;
+               if (histty[0]==0) {
+                       strcpy(histty, "/dev/");
+                       strcat(histty, ubuf.ut_line);
+               }
+       nomat:
+               ;
+       }
+cont:
+       if (logcnt==0 && histty[0]=='\0') {
+               printf("%s not logged in.\n", him);
+               exit(1);
+       }
+       fclose(uf);
+       if (histtya==0 && logcnt > 1) {
+               printf("%s logged more than once\nwriting to %s\n", him, histty+5);
+       }
+       if(histty[0] == 0) {
+               printf(him);
+               if(logcnt)
+                       printf(" not on that tty\n"); else
+                       printf(" not logged in\n");
+               exit(1);
+       }
+       if (access(histty, 0) < 0) {
+               printf("No such tty\n");
+               exit(1);
+       }
+       signal(SIGALRM, timout);
+       alarm(5);
+       if ((tf = fopen(histty, "w")) == NULL)
+               goto perm;
+       alarm(0);
+       if (fstat(fileno(tf), &stbuf) < 0)
+               goto perm;
+       if ((stbuf.st_mode&02) == 0)
+               goto perm;
+       sigs(eof);
+       fprintf(tf, "Message from ");
+#ifdef interdata
+       fprintf(tf, "(Interdata) " );
+#endif
+       fprintf(tf, "%s %s...\n\a\a\a", me, mytty);
+       fflush(tf);
+       for(;;) {
+               char buf[128];
+               i = read(0, buf, 128);
+               if(i <= 0)
+                       eof();
+               if(buf[0] == '!') {
+                       buf[i] = 0;
+                       ex(buf);
+                       continue;
+               }
+               write(fileno(tf), buf, i);
+       }
+
+perm:
+       printf("Permission denied\n");
+       exit(1);
+}
+
+timout()
+{
+
+       printf("Timeout opening his tty\n");
+       exit(1);
+}
+
+eof()
+{
+
+       fprintf(tf, "EOF\n");
+       exit(0);
+}
+
+ex(bp)
+char *bp;
+{
+       register i;
+
+       sigs(SIG_IGN);
+       i = fork();
+       if(i < 0) {
+               printf("Try again\n");
+               goto out;
+       }
+       if(i == 0) {
+               sigs((int (*)())0);
+               execl("/bin/sh", "sh", "-c", bp+1, 0);
+               exit(0);
+       }
+       while(wait((int *)NULL) != i)
+               ;
+       printf("!\n");
+out:
+       sigs(eof);
+}
+
+sigs(sig)
+int (*sig)();
+{
+       register i;
+
+       for(i=0;signum[i];i++)
+               signal(signum[i],sig);
+}
diff --git a/usr/src/cmd/yes.c b/usr/src/cmd/yes.c
new file mode 100644 (file)
index 0000000..6c638af
--- /dev/null
@@ -0,0 +1,6 @@
+main(argc, argv)
+char **argv;
+{
+       for (;;)
+               printf("%s\n", argc>1? argv[1]: "y");
+}