--- /dev/null
+/ ar -- archive/library
+
+ mov (sp)+,r0
+ sub $2,r0
+ ble userr
+ tst (sp)+
+ mov (sp)+,r1
+ clr r2
+1:
+ tstb (r1)
+ beq 1f
+ cmpb (r1),$'v
+ bne 2f
+ inc r1
+ incb vflg
+ br 1b
+2:
+ tst r2
+ bne userr
+ movb (r1)+,r2
+ br 1b
+1:
+ tst r2
+ beq userr
+ mov $arglst,r1
+1:
+ mov (sp)+,(r1)+
+ dec r0
+ bgt 1b
+ clr (r1)+
+ mov $swlst,r1
+1:
+ cmp r2,(r1)+
+ beq 1f
+ tst (r1)+
+ bne 1b
+ br userr
+1:
+ jmp *(r1)
+
+swlst:
+ 'r; comr
+ 'u; comu
+ 'd; comd
+ 'x; comx
+ 't; comt
+ 0; 0
+
+userr:
+ jsr r5,diag
+ <bad usage\n\0>
+ .even
+
+putc:
+ movb r0,ch
+ mov $1,r0
+ sys write; ch; 1
+ rts r5
+
+print:
+ movb (r1)+,r0
+ beq 1f
+ jsr r5,putc
+ br print
+1:
+ rts r5
+
+diag:
+ mov r5,r1
+ jsr r5,print
+ tst tfo
+ beq 1f
+ sys unlink; tfil
+1:
+ sys exit
+
+getaf:
+ mov arglst,0f
+ sys open; 0:..; 0
+ bes 1f
+ mov r0,afi
+ sys read; buf; 2
+ cmp buf,magic
+ bne magerr
+ tst (r5)+
+1:
+ rts r5
+
+magerr:
+ mov arglst,r1
+ jsr r5,print
+ jsr r5,diag
+ < -- not in archive format\n\0>
+ .even
+
+mktmp:
+ sys stat; tfil; buf
+ bes 1f
+ incb tfil+8
+ cmpb tfil+8,$'z
+ blo mktmp
+ br tferr
+1:
+ sys signal; 2; 1
+ ror r0
+ bcs 1f
+ sys signal; 2; done
+1:
+ sys creat; tfil; 600
+ bes tferr
+ mov r0,tfo
+ sys open; tfil; 0
+ bes tferr
+ mov r0,tfi
+ rts r5
+
+tferr:
+ jsr r5,diag
+ <cannot open temp file\n\0>
+ .even
+
+getdir:
+ mov afi,r0
+ sys read; dir; 16.
+ cmp r0,$16.
+ bne 1f
+ jsr r5,mvname
+ tst (r5)+
+1:
+ rts r5
+
+mvname:
+ mov name,rname
+ mov name+2,rname+2
+ mov name+4,rname+4
+ mov name+6,rname+6
+ rts r5
+
+skip:
+ mov size,r0
+ inc r0
+ bic $1,r0
+ mov r0,0f
+ mov afi,r0
+ sys seek; 0:..; 1
+ rts r5
+
+trim:
+ mov r0,r2
+1:
+ tstb (r0)
+ beq 1f
+ cmpb (r0)+,$'/
+ beq trim
+ br 1b
+1:
+ rts r5
+
+match:
+ mov $arglst+2,r1
+1:
+ mov (r1)+,r0
+ beq 1f
+ cmp r0,$-1
+ beq 1b
+ jsr r5,trim
+ mov $name,r0
+2:
+ cmp r0,$name+8.
+ beq 2f
+ cmpb (r0),(r2)+
+ bne 1b
+ tstb (r0)+
+ bne 2b
+2:
+ cmp (r5)+,-(r1)
+1:
+ rts r5
+
+mvfil:
+ mov (r1),9f
+ mov (r1),0f
+ sys stat; 0:..; buf
+ bes operr
+ sys open; 9:..; 0
+ bes operr
+ mov r0,fio
+ mov (r1),r0
+ mov $-1,(r1)
+ jsr r5,trim
+ mov $name,r0
+1:
+ cmp r0,$name+8.
+ beq 1f
+ movb (r2)+,(r0)+
+ bne 1b
+1:
+ mov buf+32.,mtim
+ mov buf+34.,mtim+2
+ movb buf+7.,ouid
+ movb buf+4.,mode
+ mov buf+10.,size
+ mov tfo,r0
+ sys write; dir; 16.
+ mov size,r2
+1:
+ mov fio,r0
+ sys read; buf; 512.
+ sub r0,r2
+ mov r0,0f
+ beq 1f
+ mov tfo,r0
+ sys write; buf; 0:..
+ br 1b
+1:
+ tst r2
+ bne phserr
+ bit $1,size
+ beq 1f
+ mov tfo,r0
+ sys seek; 1; 1
+1:
+ mov fio,r0
+ sys close
+ jsr r5,mvname
+ rts r5
+
+operr:
+ mov 9b,r1
+ jsr r5,print
+ jsr r5,diag
+ < -- cannot open\n\0>
+ .even
+
+phserr:
+ mov 9b,r1
+ jsr r5,print
+ jsr r5,diag
+ < -- phase error\n\0>
+ .even
+
+copyfl:
+ mov tfo,r0
+ sys write; dir; 16.
+ mov size,r1
+ mov $rname,9b
+1:
+ mov r1,0f
+ beq 1f
+ cmp r1,$512.
+ blo 2f
+ mov $512.,0f
+2:
+ mov afi,r0
+ sys read; buf; 0:..
+ sub r0,r1
+ mov r0,0f
+ beq phserr
+ mov tfo,r0
+ sys write; buf; 0:..
+ br 1b
+1:
+ bit $1,size
+ beq 1f
+ mov afi,r0
+ sys seek; 1; 1
+ mov tfo,r0
+ sys seek; 1; 1
+1:
+ rts r5
+
+xtract:
+/ movb mode,0f
+ sys creat; rname; 0:666
+ bes noxerr
+ mov r0,fio
+ mov size,r1
+ mov $rname,9b
+1:
+ mov r1,0f
+ beq 1f
+ cmp r1,$512.
+ blo 2f
+ mov $512.,0f
+2:
+ mov afi,r0
+ sys read; buf; 0:..
+ sub r0,r1
+ mov r0,0f
+ beq phserr
+ mov fio,r0
+ sys write; buf; 0:..
+ br 1b
+1:
+ mov fio,r0
+ sys close
+ bit $1,size
+ beq 1f
+ mov afi,r0
+ sys seek; 1; 1
+1:
+ mov r0,-(sp)
+ mov r1,-(sp)
+ mov mtim+2,r1
+ mov mtim,r0
+/ sys mdate
+ mov (sp)+,r1
+ mov (sp)+,r1
+ rts r5
+
+noxerr:
+ mov $rname,r1
+ jsr r5,print
+ jsr r5,diag
+ < -- cannot create\n\0>
+ .even
+
+table:
+ mov $rname,r1
+ jsr r5,print
+ mov $'\n,r0
+ jsr r5,putc
+ rts r5
+
+mesg:
+ mov r1,-(sp)
+ mov (r5)+,r0
+ tstb vflg
+ beq 1f
+ jsr r5,putc
+ mov $' ,r0
+ jsr r5,putc
+ mov $rname,r1
+ jsr r5,print
+ mov $'\n,r0
+ jsr r5,putc
+1:
+ mov (sp)+,r1
+ rts r5
+
+oldnew:
+ sys stat; rname; buf
+ bes 1f
+ cmp buf+32.,mtim
+ blo 1f
+ bhi 2f
+ cmp buf+34.,mtim+2
+ blos 1f
+2:
+ tst (r5)+
+ mov $rname,tname
+ mov $tname,r1
+1:
+ rts r5
+
+comr:
+ jsr r5,mktmp
+ jsr r5,getaf
+ br copfl
+1:
+ jsr r5,getdir
+ br copfl
+ jsr r5,match
+ br 2f
+ jsr r5,mesg; 'r
+ jsr r5,skip
+ jsr r5,mvfil
+ br 1b
+2:
+ jsr r5,copyfl
+ jsr r5,mesg; 'c
+ br 1b
+
+comu:
+ jsr r5,mktmp
+ jsr r5,getaf
+ br noaf
+1:
+ jsr r5,getdir
+ br copfl
+ tst arglst+2
+ beq 2f
+ jsr r5,match
+ br 3f
+ mov $-1,(r1)
+2:
+ jsr r5,oldnew
+ br 3f
+ jsr r5,mesg; 'r
+ jsr r5,skip
+ jsr r5,mvfil
+ br 1b
+3:
+ jsr r5,copyfl
+ jsr r5,mesg; 'c
+ br 1b
+
+comd:
+ jsr r5,mktmp
+ jsr r5,getaf
+ br noaf
+1:
+ jsr r5,getdir
+ br 1f
+ jsr r5,match
+ br 2f
+ mov $-1,(r1)
+ jsr r5,skip
+ jsr r5,mesg; 'd
+ br 1b
+2:
+ jsr r5,copyfl
+ jsr r5,mesg; 'c
+ br 1b
+1:
+ jsr r5,nfound
+ br copfl
+
+noaf:
+ jsr r5,diag
+ <no archive file\n\0>
+ .even
+
+crterr:
+ jsr r5,diag
+ <cannot create archive file\n\0>
+ .even
+
+copfl:
+ mov $arglst,r1
+ mov (r1)+,0f
+1:
+ tst (r1)+
+ beq 1f
+ cmp -2(r1),$-1
+ beq 1b
+ tst -(r1)
+ jsr r5,mvfil
+ jsr r5,mesg; 'a
+ br 1b
+1:
+ sys signal; 2; 1 / no interrupts during copy back
+ sys creat; 0:..; 666
+ bes crterr
+ mov r0,afo
+ sys write; magic; 2
+1:
+ mov tfi,r0
+ sys read; buf; 512.
+ mov r0,0f
+ beq done
+ mov afo,r0
+ sys write; buf; 0:..
+ br 1b
+
+done:
+ jsr r5,diag
+ <\0>
+ .even
+
+comx:
+ jsr r5,getaf
+ br noaf
+1:
+ jsr r5,getdir
+ br 1f
+ tst arglst+2
+ beq 3f
+ jsr r5,match
+ br 2f
+ mov $-1,(r1)
+3:
+ jsr r5,xtract
+ jsr r5,mesg; 'x
+ br 1b
+2:
+ jsr r5,skip
+ br 1b
+1:
+ jsr r5,nfound
+ br done
+
+comt:
+ jsr r5,getaf
+ br noaf
+1:
+ jsr r5,getdir
+ br 1f
+ tst arglst+2
+ beq 2f
+ jsr r5,match
+ br 3f
+ mov $-1,(r1)
+2:
+ jsr r5,table
+3:
+ jsr r5,skip
+ br 1b
+1:
+ jsr r5,nfound
+ br done
+
+nfound:
+ mov $arglst+2,r2
+1:
+ mov (r2)+,r1
+ beq 1f
+ cmp r1,$-1
+ beq 1b
+ mov $-1,-(r2)
+ jsr r5,print
+ mov $notfnd,r1
+ jsr r5,print
+ br 1b
+1:
+ rts r5
+
+notfnd:
+ < -- not found\n\0>
+ .even
+
+tfil: </tmp/vtma\0>
+ .even
+magic: -147.
+
+ .bss
+
+afi: .=.+2
+afo: .=.+2
+tfi: .=.+2
+tfo: .=.+2
+fio: .=.+2
+rname: .=.+9.
+ch: .=.+1
+vflg: .=.+1
+ .even
+tname: .=.+2
+dir:
+ name: .=.+8.
+ mtim: .=.+4
+ ouid: .=.+1
+ mode: .=.+1
+ size: .=.+2
+arglst: .=.+200.
+buf: .=.+512.
+
--- /dev/null
+/* if command */
+
+int ap;
+int ac;
+char **av;
+
+main(argc, argv)
+char *argv[];
+{
+
+ argv[argc] = 0;
+ ac = argc; av = argv; ap = 1;
+ if (argc<2) return;
+ if (exp())
+ if(doex(0)) {
+ write(1, "no command\n", 11);
+ seek(0, 0, 2);
+ }
+}
+
+char *nxtarg() {
+
+ if (ap>ac) return(0*ap++);
+ return(av[ap++]);
+}
+
+exp(s) {
+ int p1;
+
+ p1 = e1();
+ if (eq(nxtarg(), "-o")) return(p1 | exp());
+ ap--;
+ return(p1);
+}
+
+e1() {
+ int p1;
+
+ p1 = e2();
+ if (eq(nxtarg(), "-a")) return (p1 & e1());
+ ap--;
+ return(p1);
+}
+
+e2() {
+ if (eq(nxtarg(), "!"))
+ return(!e3());
+ ap--;
+ return(e3());
+}
+
+e3() {
+ int p1, ccode;
+ register char *a;
+
+ ccode = 0;
+ if ((a=nxtarg())==0) goto err;
+ if(eq(a, "(")) {
+ p1 = exp();
+ if(!eq(nxtarg(), ")")) goto err;
+ return(p1);
+ }
+
+ if(eq(a, "-r"))
+ return(tio(nxtarg(), 0));
+
+ if(eq(a, "-w"))
+ return(tio(nxtarg(), 1));
+
+ if(eq(a, "-c"))
+ return(tcreat(nxtarg()));
+
+ if(eq(a, "{")) { /* execute a command for exit code */
+ if(fork()) /*parent*/ wait(&ccode);
+ else { /*child*/
+ doex(1);
+ goto err;
+ }
+ while((a=nxtarg()) && (!eq(a,"}")));
+ return(ccode? 0 : 1);
+ }
+
+ p1 = nxtarg();
+ if (p1==0) goto err;
+ if(eq(p1, "="))
+ return(eq(a, nxtarg()));
+
+ if(eq(p1, "!="))
+ return(!eq(a, nxtarg()));
+err:
+ write(1, "if error\n", 9);
+ exit(9);
+}
+
+tio(a, f) {
+
+ a = open(a, f);
+ if (a>=0) {
+ close(a);
+ return(1);
+ }
+ return(0);
+}
+
+tcreat(a) {
+ return(1);
+}
+
+eq(a, b)
+char *a, *b;
+{
+ register int i;
+
+ i = 0;
+l:
+ if(a[i] != b[i])
+ return(0);
+ if(a[i++] == '\0')
+ return(1);
+ goto l;
+}
+
+doex(earg) {
+
+ register int np, i, c;
+ char *nargv[50], *ncom, *na;
+
+ np = 0;
+ while (na=nxtarg()) {
+ if(earg && eq(na,"}")) break;
+ nargv[np++] = na;
+ }
+ if(earg && (!eq(na, "}"))) return(9);
+ nargv[np] = 0;
+ if (np==0) return(earg);
+ execv(nargv[0], nargv, np);
+ i = 0;
+ ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ while(c=nargv[0][i]) {
+ ncom[9+i++] = c;
+ }
+ ncom[9+i] = '\0';
+ execv(ncom+4, nargv, np);
+ execv(ncom, nargv, np);
+ return(1);
+}
--- /dev/null
+char dot[] ".";
+char dotdot[] "..";
+char root[] "/";
+char name[512];
+int file, off -1;
+struct statb {int devn, inum, i[18];}x;
+struct entry { int jnum; char name[16];}y;
+
+main() {
+ int n;
+
+loop0:
+ stat(dot, &x);
+ if((file = open(dotdot,0)) < 0) prname();
+loop1:
+ if((n = read(file,&y,16)) < 16) prname();
+ if(y.jnum != x.inum)goto loop1;
+ close(file);
+ if(y.jnum == 1) ckroot();
+ cat();
+ chdir(dotdot);
+ goto loop0;
+}
+ckroot() {
+ int i, n;
+
+ if((n = stat(y.name,&x)) < 0) prname();
+ i = x.devn;
+ if((n = chdir(root)) < 0) prname();
+ if((file = open(root,0)) < 0) prname();
+loop:
+ if((n = read(file,&y,16)) < 16) prname();
+ if(y.jnum == 0) goto loop;
+ if((n = stat(y.name,&x)) < 0) prname();
+ if(x.devn != i) goto loop;
+ x.i[0] =& 060000;
+ if(x.i[0] != 040000) goto loop;
+ cat();
+ prname();
+}
+prname() {
+ name[off] = '\n';
+ write(1,name,off+1);
+ exit();
+}
+cat() {
+ int i, j;
+
+ i = -1;
+ while(y.name[++i] != 0);
+ if((off+i+2) > 511) prname();
+ for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
+ off=i+off+1;
+ name[i] = root[0];
+ for(--i; i>=0; --i) name[i] = y.name[i];
+}
--- /dev/null
+char *arg;
+int mode[3];
+
+main(argc, argv)
+char *argv[];
+{
+ int i;
+
+ gtty(1, mode);
+ while(--argc > 0) {
+
+ arg = *++argv;
+ if(eq("erase") || eq("kill") || eq("ek"))
+ mode[1] = '#@';
+ if(eq("even"))
+ set(0200);
+ if(eq("-even"))
+ reset(0200);
+ if(eq("odd"))
+ set(0100);
+ if(eq("-odd"))
+ reset(0100);
+ if(eq("raw"))
+ set(040);
+ if(eq("-raw") || eq("cooked"))
+ reset(040);
+ if(eq("-nl"))
+ set(020);
+ if(eq("nl"))
+ reset(020);
+ if(eq("echo"))
+ set(010);
+ if(eq("-echo"))
+ reset(010);
+ if(eq("lcase"))
+ set(04);
+ if(eq("-lcase"))
+ reset(04);
+ if(eq("-tabs"))
+ set(02);
+ if(eq("tabs"))
+ reset(02);
+ if(eq("-delay"))
+ set(01);
+ if(eq("delay"))
+ reset(01);
+ if(eq("hup"))
+ set(0400);
+ if(eq("-hup"))
+ reset(0400);
+ if(eq("tdelay"))
+ reset(010000);
+ if(eq("-tdelay"))
+ set(010000);
+ if(arg)
+ printf("unknown mode: %s\n", arg);
+ }
+ stty(1,mode);
+}
+
+eq(string)
+char *string;
+{
+ int i;
+
+ if(!arg)
+ return(0);
+ i = 0;
+loop:
+ if(arg[i] != string[i])
+ return(0);
+ if(arg[i++] != '\0')
+ goto loop;
+ arg = 0;
+ return(1);
+}
+
+set(b)
+{
+
+ mode[2] =| b;
+}
+
+reset(b)
+{
+
+ mode[2] =& ~b;
+}
--- /dev/null
+/ C runtime startoff
+
+.globl savr5
+
+.globl _main
+
+start:
+ setd
+ mov sp,r0
+ mov (r0),-(sp)
+ tst (r0)+
+ mov r0,2(sp)
+ jsr pc,_main
+ cmp (sp)+,(sp)+
+ clr r0
+ sys exit
+
+.bss
+savr5: .=.+2
--- /dev/null
+/ C library -- reset, setexit
+
+/ reset()
+/ will generate a "return" from
+/ the last call to
+/ setexit()
+/ by restoring sp, r5
+/ and doing a return.
+/
+/ useful for going back to the main loop
+/ after a horrible error in a lowlevel
+/ routine.
+
+.globl _setexit
+.globl _reset
+
+_setexit:
+ mov sp,ssp
+ mov r5,sr5
+ mov (sp),spc
+ rts pc
+
+_reset:
+ mov ssp,sp
+ mov sr5,r5
+ mov spc,(sp)
+ rts pc
+
+.bss
+ssp: .=.+2
+sr5: .=.+2
+spc: .=.+2
+
--- /dev/null
+#define R0 (0)
+#define R1 (-2)
+#define R2 (-9)
+#define R3 (-8)
+#define R4 (-7)
+#define R5 (-6)
+#define R6 (-3)
+#define R7 (1)
+#define RPS (2)