home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * *
- * 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);
- }
-