/* * lc [-1dlptv] [dir ...] */ #include #include #define E_ND 0 #define CHAR 1 #define BOL 2 #define EOL 3 #define ANY 4 #define CLASS 5 #define NCLASS 6 #define CLOSURE 7 #define ALPHA 8 #define NUMBER 9 #define FMAX 200 #define BEGIN { #define END } #define PMAX 128 #define DUMPER printf /* * This is the format of an * RSX directory entry. */ struct dirent BEGIN int d_fnum; int d_fseq; int d_gok; int d_name[4]; int d_ver; END ; /* * File table entry. * Saves information from the * directory. */ struct file BEGIN int f_fnum; int f_fseq; char f_name[12]; int f_ver; END ; int dflag 0; int lflag 0; int oflag 0; int pflag 0; int tflag 0; int vnflag 0; int vflag 0; struct hdr ib; int nfile; int talloc 0; int tused 0; struct file file[FMAX]; char *pp; char lbuf[20]; char pbuf[PMAX]; main(argc, argv) char *argv[]; BEGIN register char *p; register int c, i; int nf; attach(stdout); nf = argc-1; for(i=1; i= &file[FMAX]) BEGIN err(s, "too many files"); break; END p->f_fnum = db.d_fnum; p->f_fseq = db.d_fseq; r50toa(p->f_name, db.d_name, 4); p->f_ver = db.d_ver; j=0; for (i=0;i<=8 && p->f_name[i]!=' ';i++) j++; /* DUMPER("%d is the value of j in %12.12s\n",j,p->f_name);*/ copy(lbuf,(p->f_name),j); lbuf[j]=0; j=0; for (i=9;i<=11 && p->f_name[i]!=' ';i++) j++; /* DUMPER("%d is the ext value of j in %12.12s\n",j,p->f_name);*/ copy(temp,&p->f_name[9],j); temp[j]=0; concat(lbuf,lbuf,".",temp,0); /*DUMPER("lbuf,temp=%s-%s\n",lbuf,temp);*/ if (vflag == 0 && match() !=0 ) ++p; else if (vflag !=0 && match() ==0) ++p; END fclose(dir); nfile = p-file; return(1); END dirname(db, s) char *db; register char *s; BEGIN register char *d; register int c; int uic, dev, u, g; char dn[60]; dev = 0; uic = 0; u = getuid(); g = getgid(); while(*s) BEGIN if(*s == '[') BEGIN if(uic) return(0); ++uic; ++s; g = 0; while((c = *s++) && c>='0' && c<='7') g = (g<<3) + c - '0'; if(c != ',') return(0); u = 0; while((c = *s++) && c>='0' && c<='7') u = (u<<3) + c - '0'; if(c != ']') return(0); END else BEGIN if(dev) return(0); ++dev; d = s; while((c = *s++) && c!=':') ; if(c != ':') return(0); END END s = db; if(dev) while((*s++ = *d++) != ':') ; d = "[0,0]"; while(*s++ = *d++) ; --s; sprintf(dn, "%03o%03o.dir", g, u); d = dn; while(*s++ = *d++) ; return(1); END err(s, m) char *s, *m; BEGIN if(*s) fprintf(stderr, "%s: %s\n", s, m); else fprintf(stderr, "%c%s\n", *m&~' ', m+1); END sort() BEGIN register struct file *b, *m, *p; struct file tf; for(b=&file[0]; b<&file[nfile-1]; ++b) BEGIN m = b; for(p=b+1; p<&file[nfile]; ++p) if(cmp(m->f_name, p->f_name)) m = p; if(m != b) BEGIN copy(&tf, m, sizeof(tf)); copy(m, b, sizeof(tf)); copy(b, &tf, sizeof(tf)); END END END cmp(a, b) register char *a, *b; BEGIN register int n; int ca, cb; n = 12; while(n-- && ((ca=*a++)==(cb=*b++))) if(ca == '\0') break; return(ca > cb); END output(nf) BEGIN register struct file *p; register int c, n; int w; w = 1; if(!oflag && !lflag) BEGIN printf("Files:\n\n"); w = 4; END p = file; n = 0; while(nfile--) BEGIN if(n >= w) BEGIN putchar('\n'); n = 0; END c = outname(p); ++n; if(lflag || n talloc) /* Bug in TKB */ tused = talloc; printf("\nTotal allocated: %6d\n", talloc); printf("Total used: %6d\n", tused); END END outname(p) register struct file *p; BEGIN register char *s; register int c; char vb[8]; c = 0; s = p->f_name; while(s<&p->f_name[9] && *s!=' ') BEGIN putchar(*s++); ++c; END s = &p->f_name[9]; if(*s != ' ') BEGIN putchar('.'); ++c; while(s<&p->f_name[12] && *s!=' ') BEGIN putchar(*s++); ++c; END END if(c == 0) BEGIN putchar('.'); ++c; END if(vnflag) BEGIN sprintf(vb, ";%o", p->f_ver); s = vb; while(*s) BEGIN putchar(*s++); ++c; END END return(c); END longinfo(p) struct file *p; BEGIN register char *d, *t; register int n; if((n=gethdr(&ib, p->f_fnum, p->f_fseq)) < 0) BEGIN printf("Error (%d) reading file attributes", n); return; END printf("%4d%4d ", ib.h_ufat.f_efbk[1], ib.h_ufat.f_hibk[1]); talloc += ib.h_ufat.f_hibk[1]; tused += ib.h_ufat.f_efbk[1]; printf("%c%c", ib.h_ucha&UC_CON?'c':' ', ib.h_ucha&UC_DLK?'l':' '); if(pflag) BEGIN printf(" ["); for(n=0; n<16; ++n) BEGIN if(n==4 || n==8 || n==12) putchar(','); if((ib.h_fpro&01) == 0) putchar("rwed"[n&03]); else putchar('-'); ib.h_fpro >>= 1; END putchar(']'); END if(ib.i_rvdt[0]) BEGIN d = &ib.i_rvdt; t = &ib.i_rvti; END else BEGIN d = &ib.i_crdt; t = &ib.i_crti; END printf(" %.2s:%.2s", t, t+2); printf(" %.2s-%c%c%c-%.2s", d, d[2], d[3]|' ', d[4]|' ', d+5); END compile(s) register char *s; BEGIN register char *lp; register int c; int o; char *spp, *cclass(); pp = pbuf; while(c = *s++) BEGIN /* * Closure is special. */ if(c == '*') BEGIN if(pp==pbuf || (o=pp[-1])==BOL || o==EOL || o==CLOSURE) badpat(); store(E_ND); store(E_ND); spp = pp; while(--pp > lp) *pp = pp[-1]; *pp = CLOSURE; pp = spp; continue; END /* * All the rest. */ lp = pp; switch(c) BEGIN case '^': store(BOL); break; case '$': store(EOL); break; case '?': store(ANY); break; case '[': s = cclass(s); break; case '\\': if(*s) c = *s++; case '@': store(ALPHA); break; case '#': store(NUMBER); break; default: store(CHAR); store(lower(c)); END END store(E_ND); END char * cclass(s) register char *s; BEGIN register char *cp; register int c; int o; o = CLASS; if(*s == '^') BEGIN ++s; o = NCLASS; END store(o); cp = pp; store(0); /* Byte count */ while((c=*s++) && c!=']') BEGIN if(c == '\\') if((c=*s++) == '\0') badpat(); store(lower(c)); if(++*cp == 0) error("Class too complex\n"); END if(c != ']') badpat(); return(s); END store(op) BEGIN if(pp >= &pbuf[PMAX]) error("Pattern too complex\n"); *pp++ = op; END match() BEGIN char *pmatch(); register char *lll; lll = lbuf; while(*lll) BEGIN if(pmatch(lll, pbuf)) return(1); ++lll; END return(0); END char * pmatch(l, p) register char *l, *p; BEGIN register char *e; int op, c, n; char *are; while((op=*p++) != E_ND) switch(op) BEGIN case ALPHA: c=lower(*l++); if(c<'a' | c>'z') return (0); break; case NUMBER: c=*l++; if(c<'0' | c>'9') return (0); break; case CHAR: if(lower(*l++) != *p++) return(0); break; case BOL: if(l != lbuf) return(0); break; case EOL: if(*l != '\0') return(0); break; case ANY: if(*l++ == '\0') return(0); break; case CLASS: c = lower(*l++); if((n=*p++&0377) == 0) return(0); do BEGIN if(c == *p++) break; END while(--n); if(n == 0) return(0); p += n-1; break; case NCLASS: c = lower(*l++); if((n=*p++&0377) == 0) break; do BEGIN if(c == *p++) break; END while(--n); if(n) return(0); break; case CLOSURE: are = l; while(e = pmatch(l, p)) l = e; while(*p++ != E_ND) ; while(l >= are) BEGIN if(e = pmatch(l, p)) return(e); --l; END return(0); default: error("Cannot happen -- match\n"); END return(l); END lower(c) register int c; BEGIN if(c>='A' && c<='Z') c += 'a'-'A'; return(c); END badpat() BEGIN error("Bad pattern\n"); END