home *** CD-ROM | disk | FTP | other *** search
- /* -*-c,save,tab:8,indent:4-*- */
- /************************************************************************
- * XDIR.C - eXtended DIRectory program. Does all kinds of good stuff *
- * Robert Heller 16-FEB-1985 - Media Research, Ltd. *
- * (c) 1985 Media Research, Ltd. *
- * (part of Media Research, Ltd UTILS-68K package) *
- ************************************************************************
- *
- * Usage:
- * xdir [-r ][-cN ][-s ][-a ][-f ][-to ][-tr+/- ][-h+/- ][fname [fname ...]][>outfile]
- * -r - reverse alpha ordered
- * -cN - columns (default=5 iff -s,-a and -f NOT specified, else 1. also
- * iff -tr- and -h- BOTH specified then columns=1)
- * -s - size
- * -a - attributes (ie SYS/DIR, RW/RO, ARC/NOARC, etc.)
- * -f - fill (same as -s & -a)
- * -to - total - lists totals (incl. size if -s or -f)
- * -tr+/- - trailer (-tr+ [default]) or notrailer (-tr-)
- * -h+/- - header (-h+ [default]) or noheader (-h-)
- * fname - file name(s) format dr:name.type[user] - default spec is
- * curdrive:*.*[curuser]
- * >outfile - output file (CON: by default)
- *
- ************************************************************************
- */
- #include <stdio.h> /* standard I/O defs */
- #include <ctype.h> /* character types */
- #include <osif.h> /* O/S interface defs */
- #include <osiferr.h> /* O/S interface error handling */
- #include <option.h> /* option defs */
- NOWILDCARDS /* let use take care of wild cards ourselves */
- /* missing OSIF functions: */
- #define GETDRV 25 /* get current drive # */
- #define GETLOG 24 /* get login vector */
- #define GETDPB 31 /* get disk parameters */
- #define SELDRV 14 /* select drive */
-
- /* storage classes */
- #define FAST register
- #define LOCAL static
- #define GLOBAL extern
-
- /* linked list - for file name list */
- typedef struct names {
- char *name;
- struct names *next;
- } NAMES,*NAMESP;
-
- /* format for header */
- #define HFORMAT "\nDirectory %c:[%d]\n\n"
- /* trailer formats */
- #define TFORMAT1 (sflag?\
- "\nTotal of %d files, %ld KBytes/%ld directory entries.\n":\
- "\nTotal of %d files.\n")
- #define TFORMAT2 (sflag?\
- "\nGrand Total of %d files in %d directories, %ld KBytes/%ld directory entries.\n":\
- "\nGrand Total of %d files in %d directories.\n")
- /* file name format */
- #define FLEN1 15
- #define FLEN2 20
- /* size format */
- #define SFORMAT "%6ld/%-4ld "
-
- /* file search DMA block structure */
- typedef struct {
- char dr;
- char xf[8];
- char t[3];
- char fill[20];
- } SEABLK;
-
- /* DPB structure */
- typedef struct {
- short int spt; /* sectors per track */
- char bsh; /* block shift factor */
- char blm; /* block mask */
- char exm; /* extent mask */
- char z; /* reserved byte */
- short int dsm; /* disk storage mask (max block count - 1) */
- short int drm; /* directory mask (max directory entry count - 1) */
- short int zz; /* reserved word */
- short int cks; /* size of the checksum vector */
- short int off; /* number of reserved tracks */
- } DPB;
-
- /* sign macro */
- #define sign(i) (((i)<0)?(-1):(((i)>0)?(1):(0)))
-
- /* isfilech macro */
- #define isfilech(c) ((index(" <>=,!|*?&/[]().:;+-\\",c) == NULL) &&\
- (isprint(c)))
- /* search dir signs */
- #define ASSENDING (-1)
- #define DESSENDING (1)
- #define DEFAULTCOLS 5
-
- /* "global vars" */
- int sortflg = ASSENDING; /* sort direction */
- NAMESP filelist = NULL; /* file name list */
- int columns = DEFAULTCOLS, /* # columns */
- sflag = FALSE, /* size flag */
- aflag = FALSE, /* attributes flag */
- header = TRUE, /* header flag */
- trailer = TRUE, /* trailer flag */
- tflag = FALSE; /* totals flag */
- /* attribute names */
- char *attoffnames[] = {"","","","","","","","","RW","DIR",""},
- *attonnames[] = {"F1","F2","F3","F4","F5","F6","F7","F8","RO","SYS","ARC"};
- #define attname(num,ch) (((ch & 0x080) != 0)?attonnames[num]:attoffnames[num])
-
- /* commonly used functions: */
- long int __BDOS(); /* BDOS hook */
- char *index(); /* index function */
-
-
-
-
- /* main routine - process command line, fetch file names, and print results */
-
- main(argc,argv)
- FAST int argc;
- FAST char **argv;
- {
- FAST NAMESP innames,x;
- NAMESP cons(); /* list constructor funs */
-
- innames = NULL;
- while ((--argc)>0) {
- if (**(++argv) == '-') { /* switch? */
- switch(*(++(*argv))) {
- case 'r' : sortflg = DESSENDING; break;
- case 'c' : columns = atoi(++(*argv)); break;
- case 's' : sflag = TRUE; break;
- case 'a' : aflag = TRUE; break;
- case 'f' : sflag = TRUE; aflag = TRUE; break;
- case 'h' : switch (*(++(*argv))) {
- case '-' : header = FALSE; break;
- case '+' : header = TRUE; break;
- default : usage();
- } break;
- case 't' : switch (*(++(*argv))) {
- case 'o' : tflag = TRUE; break;
- case 'r' : switch (*(++(*argv))) {
- case '-' : trailer = FALSE;
- break;
- case '+' : trailer = TRUE;
- break;
- default : usage();
- } break;
- default : usage();
- } break;
- default : usage();
- }
- }
- else innames = cons(*argv,innames);
- }
- if (innames == NULL) innames = cons("*.*",innames);
- while (innames != NULL) {
- fsearch(innames->name);
- innames = innames->next;
- }
- flushdu();
- if (!header && !trailer) columns = 1;
- if (sflag || aflag) print1files();
- else printfiles();
- }
- NAMESP cons(nm,nml)
- FAST char *nm;
- FAST NAMESP nml;
- {
- FAST char *p;
- FAST int len;
- char *calloc();
- FAST NAMESP newnl;
-
- p = calloc(strlen(nm)+1,sizeof(char));
- if (p == NULL) {perror("xdir");abort(0);}
- strcpy(p,nm);
- newnl = (NAMESP) calloc(1,sizeof(NAMES));
- if (newnl == NULL) {perror("xdir");abort(0);}
- newnl->name = p;
- newnl->next = nml;
- return(newnl);
- }
- fsearch(nm)
- FAST char *nm;
- {
- LOCAL struct fcbtab seafcb;
- FAST char *p,*q;
- FAST int i,j;
- FAST int user;
- FAST char dev;
- FAST int loginv;
- FAST int curuser;
- FAST char curdev;
-
- curuser = __OSIF(USER, 0x000000FFL);
- curdev = (__OSIF(GETDRV, 0L) + 'A');
- loginv = __OSIF(GETLOG, 0L);
-
- j = 0;
- if (isalpha(*nm) && strlen(nm)>1 && *(nm+1) == ':') {
- dev = toupper(*nm);
- if (dev < 'A' || dev > 'P') badfile(q,0);
- nm = nm+2; j+=2;
- }
- else if (*nm == '*' && strlen(nm)>1 && *(nm+1) == ':') {
- dev = '*';
- nm = nm+2; j+=2;
- }
- else dev = curdev;
-
- i=8+3;
- for(p=(&seafcb.fname[0]);i>0;i--) *p++='?';
-
- p=(&seafcb.fname[0]); i = 0;
- while ((isfilech(*nm) || *nm == '?') && i<8) {
- *p++ = toupper(*nm); nm++; i++; j++;
- }
- if (*nm == '*') {nm++;j++;}
- else if (i>0 && i<8) while (i<8) {*p++ = ' '; i++;}
- while ((index(".[",*nm) == NULL) && (*nm != '\0')) {nm++;j++;}
- if (*nm == '.') {
- nm++;j++;
- p=(&seafcb.ftype[0]); i=0;
- while ((isfilech(*nm) || *nm == '?') && i<3) {
- *p++ = toupper(*nm); nm++; i++; j++;
- }
- if (*nm == '*') {nm++;j++;}
- else if (i>0 && i<3) while (i<3) {*p++ = ' '; i++;}
- }
- if (*nm == '[') {nm++;j++;
- p=nm;
- while (isdigit(*nm) || *nm == '*') {nm++;j++;}
- if (*nm != ']') badfile(q,j);
- *nm = '\0';
- if (strlen(p) == 0) user = curuser;
- else if (strcmp(p,"*") == 0) user = -1;
- else user = atoi(p);
- *nm = ']';
- nm++;j++;
- }
- else user = curuser;
- if (*nm != '\0') badfile(q,j);
-
- if (dev == '*') {
- for (i=0;i<16;i++)
- if ((loginv & (1 << i)) != 0) {
- seafcb.drive = i+1;
- sealop0(&seafcb,user,i+'A');
- }
- }
- else {
- seafcb.drive = (dev - 'A')+1;
- sealop0(&seafcb,user,dev);
- }
- __OSIF(USER, curuser);
- }
- sealop0(fcb,user,dev)
- FAST struct fcbtab *fcb;
- FAST int user;
- FAST char dev;
- {
- int i;
-
- if (user == (-1))
- for (i=0;i<16;i++) sealop(fcb,i,dev);
- else sealop(fcb,user,dev);
- }
- sealop(fcb,user,dev)
- FAST struct fcbtab *fcb;
- FAST int user;
- FAST char dev;
- {
- LOCAL SEABLK seadma[4];
- FAST int status,i;
- FAST char *p,*q;
- LOCAL char nbuff[20];
- NAMESP orderin(); /* list constructor funs */
-
- __OSIF(USER, user);
- __OSIF(SETDMA, (&seadma[0]));
- status = __OSIF(SEARCHF, fcb);
- while (status != 0x00FF) {
- p = (&nbuff[0]);
- *p++ = dev;
- *p++ = ':';
- q = (&seadma[status].xf[0]);
- i = 0;
- while ((*q & 0x7F) != ' ' && i <8) {
- *p++ = (*q++);
- i++;
- }
- *p++ = '.';
- q = (&seadma[status].t[0]);
- i=0;
- while ((*q & 0x7F) != ' ' && i < 3) {
- *p++ = (*q++);
- i++;
- }
- *p++ = '[';
- if (user > 9) {
- *p++ = (user / 10) + '0';
- *p++ = (user % 10) + '0';
- }
- else {
- *p++ = '0';
- *p++ = user + '0';
- }
- *p++ = ']';
- *p='\0';
- filelist = orderin((&nbuff[0]),filelist);
- status = __OSIF(SEARCHN, 0L);
- }
- }
- NAMESP orderin(innm,nlist)
- FAST char *innm;
- FAST NAMESP nlist;
- {
- FAST NAMESP newnl,p,q;
-
- if (nlist == NULL) return(cons(innm,nlist));
- else if (alfcmp(innm,nlist->name)) return(cons(innm,nlist));
- else {
- p = nlist;
- q = nlist->next;
- while (q != NULL && !alfcmp(innm,q->name)) {
- p=q;q=p->next;
- }
- p->next = cons(innm,q);
- return(nlist);
- }
- }
- alfcmp(s1,s2)
- FAST char *s1,*s2;
- {
- FAST *u1,*u2;
- FAST int cmp,ucmp;
-
- u1 = index(s1,'['); u2 = index(s2,'[');
- cmp = strcmp(s1,s2);
- ucmp = strcmp(u1,u2);
- if (ucmp == 0) return(sign(cmp) == sortflg);
- else return(sign(ucmp) == sortflg);
- }
- flushdu()
- {
- FAST NAMESP p,*q;
-
- p = filelist; q = (&filelist);
- while (p!=NULL && (p->next) != NULL) {
- if (strcmp(p->name,(p->next)->name) == 0) {
- *q = p->next;
- q = &(p->next);
- p = p->next;
- }
- else {
- q = &(p->next);
- p = p->next;
- }
- }
- }
- printfiles()
- {
- FAST NAMESP p;
- FAST int curcol;
- FAST char curdev,dev,*t;
- FAST int curuser,user;
- FAST int dir,files,tfiles;
-
- curdev = '@'; curuser = (-1); curcol = 0; dir=0; files=0; tfiles=0;
- for (p=filelist;p!=NULL;p=p->next) {
- if (curcol == columns && !tflag) {printf("\n");curcol=0;}
- dev = *(p->name);
- t = index(p->name,'[')+1;
- user = ((*t - '0')*10) + (*(t+1) -'0');
- if ((dev != curdev) || (user != curuser)) {
- if (curcol > 0 && !tflag) printf("\n");
- curcol = 0;
- if (trailer && files>0) printf(TFORMAT1,files);
- dir++; curdev=dev; curuser=user; files=0;
- if (header) printf(HFORMAT,dev,user);
- }
- if ((header || trailer) && !tflag) {
- *(--t) = '\0';
- prinfl((p->name)+2,FLEN1);
- *t = '[';
- }
- else if (!tflag) prinfl(p->name,FLEN2);
- curcol++;files++;tfiles++;
- }
- if (curcol>0 && !tflag) printf("\n");
- if (trailer && files > 0) printf(TFORMAT1,files);
- if (trailer && dir >1) printf(TFORMAT2,tfiles,dir);
- }
- print1files()
- {
- FAST NAMESP p;
- FAST char curdev,dev,*t,*u;
- FAST int curuser,user;
- FAST int ai,comma;
- FAST int dir,files,tfiles;
- FAST long int size,fsize,tsize;
- FAST long int dire,fdire,tdire;
- LOCAL struct fcbtab fcb;
- LOCAL DPB dpb;
- int olduser,olddrv;
-
- olduser = __OSIF(USER, 0x00FF);
- olddrv = __OSIF(GETDRV, 0);
- fsize = 0L; tsize = 0L;
- fdire = 0L; tdire = 0L;
- curdev = '@'; curuser = (-1); dir=0; files=0; tfiles=0;
- for (p=filelist;p!=NULL;p=p->next) {
- dev = *(p->name);
- t = index(p->name,'[')+1;
- user = ((*t - '0')*10) + (*(t+1) -'0');
- if ((dev != curdev) || (user != curuser)) {
- if (trailer && files>0) printf(TFORMAT1,files,fsize,fdire);
- dir++; curdev=dev; curuser=user; files=0; fsize = 0L; fdire=0L;
- if (header) printf(HFORMAT,dev,user);
- }
- if ((header || trailer) && !tflag) {
- *(--t) = '\0';
- prinfl((p->name)+2,FLEN1);
- *t = '[';
- }
- else if (!tflag) prinfl(p->name,FLEN2);
- fcb.drive = (dev - 'A') + 1;
- t = (&fcb.fname[0]); for (ai=0;ai<(8+3);ai++) *t++ = ' ';
- t = (p->name)+2; u = (&fcb.fname[0]);
- while (*t != '.') *u++ = *t++;
- t++; u = (&fcb.ftype[0]);
- while (*t != '[') *u++ = *t++;
- if (sflag) {
- __OSIF(USER, user);
- __OSIF(FILSIZ ,&fcb);
- __OSIF(USER, olduser);
- __OSIF(SELDRV, dev - 'A');
- __OSIF(GETDPB, &dpb);
- __OSIF(SELDRV, olddrv);
- size = (fcb.record + ((long) dpb.blm)) >> dpb.bsh;
- if (dpb.dsm > 255) dire = (size + 7L) >> 3;
- else dire = (size + 15L) >> 4;
- if (dpb.bsh>3) size = size << (dpb.bsh - 3);
- if (!tflag) printf(SFORMAT,size,dire);
- fsize += size; tsize += size;
- fdire += dire; tdire += dire;
- }
- if (aflag && !tflag) {
- __OSIF(USER, user);
- __OSIF(OPEN ,&fcb);
- /* __OSIF(CLOSE ,&fcb);*/
- __OSIF(USER, olduser);
- t = (&fcb.fname[0]);
- printf("("); comma = FALSE;
- for(ai = 0;ai<(8+3);ai++) {
- if (comma && strlen(attname(ai,*t))>0) printf(",");
- printf("%s",attname(ai,*t));
- if (strlen(attname(ai,*t))>0) comma = TRUE;
- t++;
- }
- printf(")");
- }
- if (!tflag) printf("\n");
- files++;tfiles++;
- }
- if (trailer && files > 0) printf(TFORMAT1,files,fsize,fdire);
- if (trailer && dir >1) printf(TFORMAT2,tfiles,dir,tsize,tdire);
- }
- usage()
- {
- fprintf(stderr,
- "Usage: xdir [-r ][-cN ][-s ][-a ][-f ][-to ][-tr+/- ][-h+/- ][fname [fname ...]][>outfile]\n");
- abort(2);
- }
- badfile(n,np)
- FAST char *n;
- FAST int np;
- {
- fprintf(stderr,"Illegal file name: %s\n ",n);
- while ((np--)>0) fprintf(stderr," ");
- fprintf(stderr,"^- parse stoped here\n");
- abort(1);
- }
- prinfl(s,l)
- FAST char *s;
- FAST int l;
- {
- while (*s != '\0') {
- printf("%c",(*s++) & 0x7F);
- l--;
- }
- while ((l--)>0) putchar(' ');
- }
-