/*--- EDIT # 0124 4 May 1982 14:38:52 DB1:[21,6]DIR.C;207 */ /*--- PREVIOUS EDIT 4 May 1982 14:28:46 DB1:[21,6]DIR.C;206 */ /* * DIR [-1dlptv] [dir ...] */ /*)BUILD $(PROGRAM) = dir $(FILES) = { dir qksort gethdr } $(TKBOPTIONS) = { LIBR = FCSRES:RO TASK = ...DIR } */ #include #include #define FMAX 1000 /* * This is the format of an * RSX directory entry. */ struct dirent { int d_fnum; int d_fseq; int d_gok; int d_name[4]; int d_ver; }; /* * File table entry. * Saves information from the * directory. */ struct file_str { int f_fnum; int f_fseq; char f_name[12]; int f_ver; }; int eflag 0; /* sort by extent as primary key */ int dflag 0; int lflag 0; int oflag 0; int pflag 0; int tflag 0; int vflag 0; struct hdr ib; int nfile; int talloc 0; int tused 0; struct file_str file[FMAX]; extern char $$uic[1]; extern int fn_cmp(); /* compare routine for qksort */ FILE *dir; main(argc, argv) char *argv[]; { register char *p; register int c, i; int nf; if (ftty(stdout)) tiatt(); /* attach the terminal so CTRL/O works */ nf = argc-1; for(i=1; i 500) fprintf (stderr, "Have patience. I am sorting %d filenames.\n", nfile); qksort(file, nfile, sizeof file[0], &fn_cmp); } if(b) printf("\n%s:\n", s); output(); fclose (dir); } collect(s) char *s; { register struct file_str *p; struct dirent db; char dn[40]; char sel[40]; /* filename selector string */ char *cp, *xp; int i; if(!dirname(dn, s, sel)) { err(s, "bad format"); return(0); } /* printf("dn:'%s'\tsel:'%s'\n", dn, sel);*/ if((dir=fopen(dn, "run")) == NULL) { err(s, "cannot list"); return(0); } p = file; while(fget(&db, sizeof(db), dir) == sizeof(db)) { if((db.d_fnum == 0) || (db.d_gok != 0)) continue; if(p >= &file[FMAX]) { err(s, "too many files"); break; } 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; if (sel[0] != NULL) { /* see if the filename matches */ for (cp = dn, xp = p->f_name, i = 0; i < 9; i++) { if ((*cp = *xp++) != ' ') cp++; } *cp++ = '.'; for (; i < 12; i++) { if ((*cp = *xp++) != ' ') cp++; } *cp++ = ';'; *cp = NULL; /* printf("\ntry:%s\n", dn);*/ if (!match(dn, sel)) --p; /* skip this one, it doesn't match */ } ++p; } nfile = p-file; return(1); } /*************************************/ dirname(db, s, sel) char *db; register char *s; char *sel; { register char *d, *s1; register int c; int uic, dev, u, g; char dn[60]; dev = 0; uic = 0; *sel = *db = NULL; u = $$uic[0] & 0377; g = $$uic[1] & 0377; /* LOOK FOR THE DEVICE NAME */ s1 = s; while (*s1) { if (*s1++ == ':') { dev++; d = s; s = s1; } } /* Collect the UIC (if any) */ if(*s == '[') { ++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); } /* The rest is the filename selector, same as SRD: * * matches 0 or more characters (different than the next one. * % matches one character * ? matches one character * ; ends the specifier early * All selectors are assumed to be ended with '*;'. */ if (*s) { while ((c = *s++) != NULL) { *sel++ = toupper(c); if (c == '*') { /* two stars in a row collapse to just one */ while (*s != NULL && *s == '*') s++; } else if (c == '%' || c == '.' || c == ';' || isdigit(c) || isalpha(c)) { } else if (c == '?') *(sel-1) = '%'; else return (0); /* bad pattern */ } if (*(sel-1) != '*') *sel++ = '*'; *sel++ = ';'; } *sel == NULL; /* build the directory filename string */ 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); } err(s, m) char *s, *m; { if(*s) fprintf(stderr, "%s: %s\n", s, m); else fprintf(stderr, "%c%s\n", *m&~' ', m+1); } /***************************************/ /* Simple pattern matcher */ match(s, t) register char *s; /* string */ register char *t; /* template */ { while (1) { /* printf("str:%s temp:%s\n", s, t);*/ /* star matches zero or more chars, * extending each time the rest fails */ if (*t == '*') { t++; while (1) { if (match(s, t)) return (1);/* yup, it did */ if (*s++ == ';') return (0);/* at end of target string, fail*/ } } /* Swallow some */ while (*s == *t) { if (*s++ == ';') return (1); /* at end on both */ t++; } /* Wild-card single char works if not at end of target */ if (*t != '*') if (*t++ != '%' || *s++ == ';') return (0); } return(1); } /***************************************/ /* Compare 2 file-names, returning -1, =0 +1, same as * strcmp */ fn_cmp (f1, f2) struct file_str *f1, *f2; /* given the file struct (YUCH!) */ { int c; /* comparison result */ if (!eflag) c = bufcmp(f1->f_name, f2->f_name, 12); else { c = bufcmp (&(f1->f_name[9]), &(f2->f_name[9]), 3); if (!c) bufcmp (f1->f_name, f2->f_name, 9); } if (!c) c = f1->f_ver - f2->f_ver; return (c); } /******* compare 2 char buffers, similar to * strcmp, but going by size */ bufcmp (a, b, size) register char *a, *b; register int size; { int c; c = 0; while ((size--) && (!c)) { c = (*a++) - (*b++); } return (c); } output(nf) { register struct file_str *p; register int c, n; int w; w = 1; if(!oflag && !lflag) { w = 4; } p = file; n = 0; while(nfile--) { if(n >= w) { putchar('\n'); n = 0; } c = outname(p); if (c) { ++n; if(lflag || nf_name; /* IF we are not printing version numbers but are sorting, only print the highest version file. They are in ascending order, so only print this one if the next one has a different name */ temp = p; temp++; if ((!dflag) && (!vflag) && !bufcmp(p->f_name, temp->f_name, 12)) { /* printf ("%06o %06o \n",p,temp); */ return (0); } while(s<&p->f_name[9] && *s!=' ') { putchar(*s++); ++c; } s = &p->f_name[9]; if(*s != ' ') { putchar('.'); ++c; while(s<&p->f_name[12] && *s!=' ') { putchar(*s++); ++c; } } if(c == 0) { putchar('.'); ++c; } if(vflag) { sprintf(vb, ";%o", p->f_ver); s = vb; while(*s) { putchar(*s++); ++c; } } return(c); } longinfo(p) struct file_str *p; { register char *d, *t; register int n; if((n=gethdr(&ib, p->f_fnum, p->f_fseq, dir)) < 0) { printf("Error (%d) reading file attributes", n); return; } if ((ib.h_ufat.f_ffby == 0) && (ib.h_ufat.f_efbk[1] !=0 )) ib.h_ufat.f_efbk[1] -= 1; 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) { printf(" ["); for(n=0; n<16; ++n) { if(n==4 || n==8 || n==12) putchar(','); if((ib.h_fpro&01) == 0) putchar("RWED"[n&03]); else putchar('-'); ib.h_fpro >>= 1; } putchar(']'); } d = &ib.i_crdt; t = &ib.i_crti; printf(" %.2s:%.2s", t, t+2); printf(" %.2s-%c%c%c-%.2s", d, d[2], d[3]|' ', d[4]|' ', d+5); if(ib.i_rvdt[0]) { if ( !(tflag && pflag)) printf(" "); d = &ib.i_rvdt; t = &ib.i_rvti; printf(" %.2s:%.2s", t, t+2); printf(" %.2s-%c%c%c-%.2s", d, d[2], d[3]|' ', d[4]|' ', d+5); } }