/**************************************************************** * * * ls.c - CP/M Directory lising program * * Written in BDS C * * Written by: Bob Longoria * * 9-Jan-82 * * * * The program lists the directory in several different * * formats depending on switches set in the command * * line (ala C). Explanation of the switches follows: * * * * Size specification: * * -f Lists full directory (file size in * * records, size file takes in disk * * space, and the files attributes * * -b Lists brief directory (file size in * * records only * * default Lists file names only * * Attribute specification: * * -n Lists files that are SYS only * * -r Lists files that are R/O only * * -w Lists files that are R/W only * * -a Lists files regardless of attributes * * default Lists files that are DIR only * * (corresponds to CP/M dir) * * Sort specification: * * -s Sorts listed files alphabettically * * default Does not sort files * * Case specification: * * -u Lists information in upper case * * default Lists information in lower case * * * * For the size or attributes specifications - if two * * of any switches in either of these groups are set - * * a conflict arises and a warning is issued and the * * default setting for the group is set. * * e.g. ls *.com -fb This command asks for a full * * and a brief listing at the same time. Here warning * * is issued and default set (brief, brief listing) * * Switches may be set in any order and can be con- * * catenated or separated. * * e.g. ls *.com -fasl does the same as * * ls *.com -a -s -fl * * * ****************************************************************/ #include "bdscio.h" /* Standard header file */ #define DMABUF 0x0080 /* Default DMA buffer address */ #define MASK 0x80 /* Attribute bit mask */ #define SSIZE 16 /* No of significant fcb bytes */ #define FCBADR 0x005c /* Default fcb address */ #define FCBS 128 /* Define max number of directory entries */ int usr; /* Current user number */ int dsk; /* Currently selected disk */ int blm; main(argc,argv) int argc; /* argument count */ char **argv; /* argument vector */ { char *fcb_ptr[FCBS]; int nfcbs, count, tot; int size_sw, attr_sw; int sort_sw, case_sw; int blm; _allocp = NULL; size_sw = attr_sw = sort_sw = case_sw = 0; get_args(&size_sw, &attr_sw, &sort_sw, &case_sw, argc, argv); get_params(); if ((count = save_fcb(fcb_ptr,attr_sw,&tot)) == -1){ printf("Warning: FCB list too large for available memory\n"); exit(); } else if (count == 0){ /* no match found */ printf("No match found for %s\n",argv[1]); exit(); } else { /* There may be a match */ if (sort_sw) sort_fcb(fcb_ptr,count,11); list_fcbs(fcb_ptr, size_sw, case_sw, count, tot); } } save_fcb(fcb_ptr, attr, ncnt) char *fcb_ptr[]; char *ncnt; int attr; { int nsave,n; char *p, *alloc(), *buf_ptr; char ro, sys; char cusr, fusr; cusr = usr; *ncnt = nsave = 0; if ((n = bdos(17,FCBADR)) == 255) return(0); do { (*ncnt)++; buf_ptr = DMABUF+32*n; sys = *(buf_ptr+10) & MASK; ro = *(buf_ptr+9) & MASK; fusr = *buf_ptr; if (((attr == 1 && sys) || (attr == 2 && ro) || (attr == 0 && !sys) || (attr == 3) || (attr == 4 && !ro)) && ((fusr ^ cusr) == 0)) { if ((p = alloc(SSIZE)) == NULL) return(-1); copy_fcb(p, buf_ptr); fcb_ptr[nsave++] = p; } } while ((n=bdos(18,FCBADR)) != 255); return (nsave); } list_fcbs(fcb_ptr, size, ucase, count, tot) char *fcb_ptr[]; int size, ucase; int count, tot; { int i; char sys, ro; char *name; unsigned n, s, fsize(); unsigned tblks, ksize; tblks = ksize = 0; name = " "; printf("Directory for Disk %c: User %2d:\n", dsk+'A', usr); for (i = 0; i < count; i++) { n = fsize(fcb_ptr[i]); s = (n/blm)*(blm/8)+((n%blm) ? blm/8 : 0); tblks += n; ksize += s; strset(name, fcb_ptr[i], ucase); switch (size) { case 0: printf("%s%s", name, (i%5==4 || i==count-1) ? "\n" : " | "); break; case 1: printf("%s%5u", name, n); printf("%s", (i%4==3 || i==count-1) ? "\n" : " | "); break; case 2: printf("%s%6u%4dK", name, n, s); sys = *(fcb_ptr[i]+10) & MASK; ro = *(fcb_ptr[i]+9) & MASK; if (ucase) printf("%s%s", (sys) ? " SYS" : " DIR", (ro) ? " R/O" : " R/W"); else printf("%s%s", (sys) ? " sys" : " dir", (ro) ? " r/o" : " r/w"); printf("%s", (i%2==1 || i==count-1) ? "\n" : " "); break; } } printf("\nListed %d/%d files",count,tot); printf(" %u/%u Blocks used",tblks, ksize*8); printf(" %uK Disk space used\n",ksize); } copy_fcb(p, s) /* Copy s to p */ char *p, *s; { int i; for (i=0; i < SSIZE; i++) *(p+i) = *(s+i); } strset(s, t, c) /* Copy t to s */ char *s, *t; int c; { int i; for (i = 0; i < 12; i++) if (i < 8) *(s+i) = (c) ? *(t+i+1) : tolower(*(t+i+1) & ~MASK); else if (i == 8) ; else *(s+i) = (c) ? *(t+i) : tolower(*(t+i) & ~MASK); } get_args (psize, pattr, psort, pcase, argc, argv) char *psize, *pattr, *psort, *pcase; int argc; char *argv[]; { char *sptr; while (--argc > 0) if ((*++argv)[0] == '-') for (sptr = argv[0]+1; *sptr != '\0'; sptr++) switch (*sptr) { case 'F': if (*psize == 0) *psize = 2; else { printf("Warning: Size switch conflict - Default set\n"); *psize = 0; } break; case 'B': if (*psize == 0) *psize = 1; else { printf("Warning: Size switch conflict - Default set\n"); *psize = 0; } break; case 'A': if (*pattr == 0) *pattr = 3; else { printf("Warning: Attr switch conflict - Default set\n"); *pattr = 0; } break; case 'N': if (*pattr == 0) *pattr = 1; else { printf("Warning: Attr switch conflict - Default set\n"); *pattr = 0; } break; case 'R': if (*pattr == 0) *pattr = 2; else { printf("Warning: Attr switch conflict - Default set\n"); *pattr = 0; } break; case 'W': if (*pattr == 0) *pattr = 4; else { printf("Warning: Attr switch conflict - Default set\n"); *pattr = 0; } break; case 'S': *psort = 1; break; case 'U': *pcase = 1; break; default: printf("Warning: Illegal switch (%c) - Ignored\n",*sptr); } } sort_fcb(v, n, num) char *v[]; int n, num; { int gap, i, j; char *temp; for (gap = n/2; gap > 0; gap /= 2) for (i = gap; i < n; i++) for (j = i-gap; j >=0; j -= gap) { if (sstrcmp(v[j], v[j+gap], num) <= 0) break; temp = v[j]; v[j] = v[j+gap]; v[j+gap] = temp; } } sstrcmp(s, t, num) char *s, *t; int num; { int i; i = 1; while (*(s+i) == *(t+i)) if (++i > num) return(0); return (*(s+i) - *(t+i)); } unsigned fsize(ptr) char *ptr; { char *p; int ex; unsigned n; unsigned *tmptr; ex = *(ptr+12); n = *(ptr+15); if (ex != 0 && n != 128) n = ex*128+n; else if (n == 128) { if ((p = alloc(SSIZE+20)) == NULL) return(0); copy_fcb(p, ptr); bdos(35,p); tmptr = p+33; n = *tmptr; } return(n); } get_params() { char *dpb_ptr; char *buf_ptr; buf_ptr = 0x005c; dsk = (*buf_ptr & 0x0f)-1; if (dsk < 0) dsk = bdos(25,0); bdos(14,dsk); dpb_ptr = bdos(31,dsk); blm = *(dpb_ptr+3)+1; usr = bdos(32,0x00ff); } .