home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol132 / ls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-04-29  |  7.5 KB  |  327 lines

  1. /**************************************************************** 
  2.  *                                * 
  3.  *    ls.c  -  CP/M Directory lising program            * 
  4.  *         Written in BDS C                  * 
  5.  *         Written by: Bob Longoria            *  
  6.  *                     9-Jan-82                *
  7.  *                                *
  8.  *    The program lists the directory in several different    *
  9.  *    formats depending on switches set in the command    *
  10.  *    line (ala C).    Explanation of the switches follows:    *
  11.  *                                *
  12.  *    Size specification:                    *
  13.  *        -f    Lists full directory (file size in    *
  14.  *            records, size file takes in disk    *
  15.  *            space, and the files attributes        *
  16.  *        -b    Lists brief directory (file size in    *
  17.  *            records only                *
  18.  *       default    Lists file names only            *
  19.  *    Attribute specification:                *
  20.  *        -n    Lists files that are SYS only         *
  21.  *        -r    Lists files that are R/O only        *
  22.  *        -w    Lists files that are R/W only        *
  23.  *        -a    Lists files regardless of attributes    *
  24.  *       default    Lists files that are DIR only        *
  25.  *            (corresponds to CP/M dir)        *
  26.  *    Sort specification:                    *
  27.  *        -s    Sorts listed files alphabettically    *
  28.  *       default    Does not sort files            *
  29.  *    Case specification:                    *
  30.  *        -u    Lists information in upper case        *
  31.  *       default    Lists information in lower case        *
  32.  *                                *
  33.  *    For the size or attributes specifications - if two    *
  34.  *    of any switches in either of these groups are set -    *
  35.  *    a conflict arises and a warning is issued and the       *
  36.  *    default setting for the group is set.            *
  37.  *    e.g. ls *.com -fb    This command asks for a full    *
  38.  *    and a brief listing at the same time.  Here warning    *
  39.  *    is issued and default set (brief, brief listing)    *
  40.  *    Switches may be set in any order and can be con-    *
  41.  *    catenated or separated.                    *
  42.  *    e.g. ls *.com -fasl does the same as            *
  43.  *    ls *.com -a -s -fl                    *
  44.  *                                *
  45.  ****************************************************************/
  46.  
  47. #include "bdscio.h"    /* Standard header file */
  48. #define DMABUF 0x0080    /* Default DMA buffer address */
  49. #define MASK   0x80    /* Attribute bit mask */
  50. #define SSIZE  16    /* No of significant fcb bytes */
  51. #define FCBADR 0x005c    /* Default fcb address */
  52. #define FCBS   128    /* Define max number of directory entries */
  53. int usr;        /* Current user number */
  54. int dsk;        /* Currently selected disk */
  55. int blm;
  56.  
  57. main(argc,argv)
  58. int argc;        /* argument count */
  59. char **argv;        /* argument vector */
  60. {
  61.   char *fcb_ptr[FCBS];
  62.   int nfcbs, count, tot;
  63.   int size_sw, attr_sw;
  64.   int sort_sw, case_sw;
  65.   int blm;
  66.  
  67.   _allocp = NULL;
  68.   size_sw = attr_sw = sort_sw = case_sw = 0;
  69.   get_args(&size_sw, &attr_sw, &sort_sw, &case_sw, argc, argv);
  70.   get_params();
  71.   if ((count = save_fcb(fcb_ptr,attr_sw,&tot)) == -1){ 
  72.     printf("Warning: FCB list too large for available memory\n");
  73.     exit();
  74.     }
  75.   else if (count == 0){ /* no match found */
  76.     printf("No match found for %s\n",argv[1]);
  77.     exit();
  78.     }
  79.   else {        /* There may be a match */
  80.     if (sort_sw)
  81.       sort_fcb(fcb_ptr,count,11);
  82.     list_fcbs(fcb_ptr, size_sw, case_sw, count, tot);
  83.     }
  84. }
  85.  
  86. save_fcb(fcb_ptr, attr, ncnt)
  87. char *fcb_ptr[];
  88. char *ncnt;
  89. int attr;
  90. {
  91.   int nsave,n;
  92.   char *p, *alloc(), *buf_ptr;
  93.   char ro, sys;
  94.   char cusr, fusr;
  95.  
  96.   cusr = usr;
  97.   *ncnt = nsave = 0;
  98.   if ((n = bdos(17,FCBADR)) == 255)
  99.     return(0);
  100.     do {
  101.       (*ncnt)++;
  102.       buf_ptr = DMABUF+32*n;
  103.       sys = *(buf_ptr+10) & MASK;
  104.       ro  = *(buf_ptr+9) & MASK;
  105.       fusr = *buf_ptr;
  106.       if (((attr == 1 &&  sys) || (attr == 2 && ro) ||
  107.       (attr == 0 && !sys) || (attr == 3) ||
  108.       (attr == 4 && !ro)) && ((fusr ^ cusr) == 0)) {
  109.     if ((p = alloc(SSIZE)) == NULL)
  110.       return(-1);
  111.     copy_fcb(p, buf_ptr);
  112.     fcb_ptr[nsave++] = p;
  113.       } 
  114.     }
  115.     while ((n=bdos(18,FCBADR)) != 255);
  116.   return (nsave);
  117. }
  118.  
  119. list_fcbs(fcb_ptr, size, ucase, count, tot)
  120. char *fcb_ptr[];
  121. int size, ucase;
  122. int count, tot;
  123. {
  124.   int i;
  125.   char sys, ro;
  126.   char *name;
  127.   unsigned n, s, fsize();
  128.   unsigned tblks, ksize;
  129.   
  130.   tblks = ksize = 0;
  131.   name = "            ";
  132.   printf("Directory for Disk %c:  User %2d:\n", dsk+'A', usr);
  133.   for (i = 0; i < count; i++) {
  134.     n = fsize(fcb_ptr[i]);
  135.     s = (n/blm)*(blm/8)+((n%blm) ? blm/8 : 0);
  136.     tblks += n;
  137.     ksize += s;
  138.     strset(name, fcb_ptr[i], ucase);
  139.     switch (size) {
  140.       case 0:
  141.         printf("%s%s", name, (i%5==4 || i==count-1) ? "\n" : " | ");
  142.         break;
  143.       case 1:
  144.     printf("%s%5u", name, n);
  145.     printf("%s", (i%4==3 || i==count-1) ? "\n" : " | ");
  146.     break;
  147.       case 2:
  148.     printf("%s%6u%4dK", name, n, s);
  149.     sys = *(fcb_ptr[i]+10) & MASK;
  150.     ro = *(fcb_ptr[i]+9) & MASK;
  151.     if (ucase)
  152.     printf("%s%s", (sys) ? "  SYS" : "  DIR", (ro) ? "  R/O" : "  R/W");
  153.     else
  154.     printf("%s%s", (sys) ? "  sys" : "  dir", (ro) ? "  r/o" : "  r/w");
  155.     printf("%s", (i%2==1 || i==count-1) ? "\n" : "           ");
  156.     break;
  157.       }
  158.   }
  159.   printf("\nListed %d/%d files",count,tot);
  160.   printf("   %u/%u Blocks used",tblks, ksize*8);
  161.   printf("   %uK Disk space used\n",ksize);
  162. }
  163.  
  164. copy_fcb(p, s)        /* Copy s to p */
  165. char *p, *s;
  166. {
  167.   int i;
  168.  
  169.   for (i=0; i < SSIZE; i++)
  170.     *(p+i) = *(s+i);
  171. }
  172.  
  173. strset(s, t, c)        /* Copy t to s */
  174. char *s, *t;
  175. int c;
  176. {
  177.   int i;
  178.  
  179.   for (i = 0; i < 12; i++)
  180.     if (i < 8)
  181.       *(s+i) = (c) ? *(t+i+1) : tolower(*(t+i+1) & ~MASK);
  182.     else if (i == 8)
  183.       ;
  184.     else
  185.       *(s+i) = (c) ? *(t+i) : tolower(*(t+i) & ~MASK);
  186. }
  187.  
  188. get_args (psize, pattr, psort, pcase, argc, argv)
  189. char *psize, *pattr, *psort, *pcase;
  190. int argc;
  191. char *argv[];
  192. {
  193.   char *sptr;
  194.  
  195.   while (--argc > 0)
  196.     if ((*++argv)[0] == '-')
  197.       for (sptr = argv[0]+1; *sptr != '\0'; sptr++)
  198.         switch (*sptr) {
  199.         case 'F':
  200.           if (*psize == 0)
  201.             *psize = 2;
  202.           else {
  203.          printf("Warning: Size switch conflict - Default set\n");
  204.         *psize = 0;
  205.         }
  206.       break;
  207.         case 'B':
  208.       if (*psize == 0)
  209.         *psize = 1;
  210.       else {
  211.         printf("Warning: Size switch conflict - Default set\n");
  212.         *psize = 0;
  213.         }
  214.       break;
  215.         case 'A':
  216.       if (*pattr == 0)
  217.         *pattr = 3;
  218.       else {
  219.         printf("Warning: Attr switch conflict - Default set\n");
  220.         *pattr = 0;
  221.         }
  222.       break;
  223.         case 'N':
  224.       if (*pattr == 0)
  225.         *pattr = 1;
  226.       else {
  227.         printf("Warning: Attr switch conflict - Default set\n");
  228.         *pattr = 0;
  229.         }
  230.       break;
  231.         case 'R':
  232.       if (*pattr == 0)
  233.         *pattr = 2;
  234.       else {
  235.         printf("Warning: Attr switch conflict - Default set\n");
  236.         *pattr = 0;
  237.         }
  238.       break;
  239.     case 'W':
  240.       if (*pattr == 0)
  241.         *pattr = 4;
  242.       else {
  243.         printf("Warning: Attr switch conflict - Default set\n");
  244.         *pattr = 0;
  245.         }
  246.       break;
  247.         case 'S':
  248.       *psort = 1;
  249.       break;
  250.     case 'U':
  251.       *pcase = 1;
  252.       break;
  253.         default:
  254.       printf("Warning: Illegal switch (%c) - Ignored\n",*sptr);
  255.         }
  256. }
  257.  
  258. sort_fcb(v, n, num)
  259. char *v[];
  260. int n, num;
  261. {
  262.   int gap, i, j;
  263.   char *temp;
  264.  
  265.   for (gap = n/2; gap > 0; gap /= 2)
  266.     for (i = gap; i < n; i++)
  267.       for (j = i-gap; j >=0; j -= gap) {
  268.     if (sstrcmp(v[j], v[j+gap], num) <= 0)
  269.       break;
  270.     temp = v[j];
  271.     v[j] = v[j+gap];
  272.     v[j+gap] = temp;
  273.         }
  274. }
  275.  
  276. sstrcmp(s, t, num)
  277. char *s, *t;
  278. int num;
  279. {
  280.   int i;
  281.  
  282.   i = 1;
  283.   while (*(s+i) == *(t+i))
  284.     if (++i > num)
  285.       return(0);
  286.   return (*(s+i) - *(t+i));
  287. }
  288.  
  289. unsigned fsize(ptr)
  290. char *ptr;
  291. {
  292.   char *p;
  293.   int ex;
  294.   unsigned n;
  295.   unsigned *tmptr;
  296.  
  297.   ex = *(ptr+12);
  298.   n = *(ptr+15);
  299.   if (ex != 0 && n != 128)
  300.     n = ex*128+n;
  301.   else
  302.     if (n == 128) {
  303.     if ((p = alloc(SSIZE+20)) == NULL)
  304.       return(0);
  305.     copy_fcb(p, ptr);
  306.     bdos(35,p);
  307.     tmptr = p+33;
  308.     n = *tmptr;
  309.     }
  310.   return(n);
  311. }
  312.  
  313. get_params()
  314. {
  315.   char *dpb_ptr;
  316.   char *buf_ptr;
  317.  
  318.   buf_ptr = 0x005c;
  319.   dsk = (*buf_ptr & 0x0f)-1;
  320.   if (dsk < 0)
  321.     dsk = bdos(25,0);
  322.   bdos(14,dsk);
  323.   dpb_ptr = bdos(31,dsk);
  324.   blm = *(dpb_ptr+3)+1;
  325.   usr = bdos(32,0x00ff);
  326. }
  327.