home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 165 / DSKPARM.ZIP / SHOW.C < prev    next >
Text File  |  1987-12-26  |  9KB  |  309 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <dos.h>
  5. #include <malloc.h>
  6. #include <direct.h>
  7. #include <string.h>
  8.  
  9. /* show -- This program rints an enhanced directory
  10. **        listing for a disk.  The output resembles that
  11. **        from the DOS DIR comand, but includes the
  12. **        following additional information for each file:
  13. **
  14. **        1)  The flag settings for the file. 'a' if the
  15. **        "archive" bit is set, 'h' if the "hidden"
  16. **        bit is set, 's' if the "system" bit is
  17. **        set and 'r' if the "read only" bit is set.
  18. **
  19. **        2)  The actual amount of space allocated for
  20. **        storage of the file, reflecting the number
  21. **        of clusters allocated to the file.
  22. **
  23. **        3)  The cluster chaining for the file.  Cluster
  24. **        numbers are shown in hex.  Gaps are shown
  25. **        by starting a new line.
  26. **
  27. **        Also displayed are totals for bytes in files,
  28. **        total bytes allocated to files, number of files,
  29. **        (broken down as contiguous and noncontigous),
  30. **        number of clusters used, and bytes of free
  31. **        space remaining.
  32. **
  33. **        Usage: show [d:filename.exe [a:]]
  34. **
  35. **        If the drive specification d: is omitted, the
  36. **        current default drive is assumed.  If the
  37. **        filename or extension are omitted, '*' is
  38. **        assumed.
  39. **
  40. **        If the alternate drive specification a: is given
  41. **        the program will compute the amount of space
  42. **        the specified files would require on this
  43. **        alternate drive along with the actual amount of
  44. **        space currently available on that drive.
  45. **
  46. **        Compiler:    Microsoft C V4.0
  47. **        Options:    /Zp (pack arrays)  (V3.0 requires /Ze)
  48. **
  49. **        External modules:
  50. **            absread()
  51. **
  52. **        Version 1.33    February 6, 1986
  53. **
  54. **        Glenn F. Roberts
  55. */
  56. #define TRUE 1
  57. #define FALSE 0
  58. #define MIN_VERSION 200            /* DOS 2.0 */
  59. #define MAX_VERSION 330            /* DOS 3.3 */
  60. #define MAX_CWD_LEN 63
  61.  
  62. #include "structs.h"
  63. #include "dosfns.h"
  64.  
  65. main(argc, argv)
  66. int argc;
  67. char *argv[];
  68. {
  69.     int ver;
  70.     static struct ext_fcb fcb = {
  71.         0xFF,0,0,0,0,0,0,0,
  72.         '?','?','?','?','?','?','?','?','?','?','?',
  73.         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  74.     };
  75.     static struct ext_fcb alt_fcb = {
  76.         0xFF,0,0,0,0,0,0,0,
  77.         '?','?','?','?','?','?','?','?','?','?','?',
  78.         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  79.     };
  80.     
  81.     ver = _osmajor*100+_osminor;
  82.     if ((ver < MIN_VERSION) || (ver > MAX_VERSION))
  83.       printf("Incorrect DOS version %d\n", ver);
  84.     else if (!((--argc > 0) ?
  85.       (parse(*++argv, &fcb.drive_id, 12) != 255) : TRUE))
  86.       printf("Invalid drive specification\n");
  87.     else if (!((--argc > 0) ?
  88.       (parse(*++argv, &alt_fcb.drive_id, 1) != 255) : TRUE))
  89.       printf("Invalid alternate drive\n");
  90.     else {
  91.         fcb.fcb_hdr.attrib =
  92.           HIDDEN | ARCHIVE | SYSTEM | READ_ONLY;
  93.         do_entry(&fcb, alt_fcb.drive_id-1);
  94.     }
  95. }
  96.  
  97. /* print_vname -- print volume name and
  98. **        current working directory
  99. */
  100. print_vname(drive)
  101. int drive;
  102. {
  103.     struct extended_entry dir_entry;
  104.     static struct ext_fcb vol_fcb = {
  105.         0xFF,0,0,0,0,0,VOL_ENTRY,0,
  106.         '?','?','?','?','?','?','?','?','?','?','?',
  107.         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  108.     };
  109.     int i, drive_save;
  110.     char current_dir[MAX_CWD_LEN+1];
  111.     
  112.     printf("\tVolume in Drive %c is ", (drive + 'A'));
  113.     setdta(&dir_entry);
  114.     vol_fcb.drive_id = drive+1;
  115.     if (search_first(&vol_fcb) != 255) {
  116.         for (i=0; i<11; i++)
  117.           putchar(dir_entry.body.filname[i]);
  118.         putchar('\n');
  119.     }
  120.     else
  121.       printf("Unlabeled\n");
  122.     printf("\tDirectory of ");
  123.     drive_save = current_drv();
  124.     select_drv(drive);
  125.     getcwd(current_dir, MAX_CWD_LEN);
  126.     printf("%s\n\n", current_dir);
  127.     select_drv(drive_save);
  128. }
  129.  
  130. /* print_flags -- print ASCII indication of file
  131. **        flag settings.
  132. */
  133. print_flags(attrib)
  134. char attrib;
  135. {
  136.     char str[7];
  137.     
  138.     strcpy(str, "       ");
  139.     if (attrib & ARCHIVE)    str[2] = 'a';
  140.     if (attrib & HIDDEN)    str[3] = 'h';
  141.     if (attrib & READ_ONLY)    str[4] = 'r';
  142.     if (attrib & SYSTEM)     str[5] = 's';
  143.     printf("%s", str);
  144. }
  145.  
  146. /* do_entry -- print output for file specification
  147. **        as parsed in fcb.
  148. */
  149. do_entry(fcb, alt_drive)
  150. struct ext_fcb *fcb;
  151. int alt_drive;
  152. {
  153.     unsigned cluster, avail, total, sectsize;
  154.     int i, drive, num_files, num_contig, total_clusters;
  155.     int twelve_bit_fat, cluster_count, alt_clsize, alt_total;
  156.     long size_total, actual_total;
  157.     struct extended_entry dir_entry;
  158.     struct disk_table far *get_table(), far *tbl, far *alt_tbl;
  159.     unsigned char *fat, cre_date[15], cre_time[15];
  160.     
  161.     /* Get target drive information */
  162.     drive = (fcb->drive_id == 0) ? current_drv() : fcb->drive_id-1;
  163.     print_vname(drive);
  164.     tbl = get_table(drive);
  165.     twelve_bit_fat = tbl->last_cluster < MAX_12BIT;
  166.     
  167.     /* If alternate drive given, look up drive info. */
  168.     if (alt_drive != -1) {
  169.         alt_tbl = get_table(alt_drive);
  170.         alt_clsize = alt_tbl->sector_size * (alt_tbl->cluster_size+1);
  171.     }
  172.     
  173.     /* Read File Allocation Table */
  174.     fat = (unsigned char *) malloc(tbl->fat_size*tbl->sector_size);
  175.     absread(drive, tbl->fat_size, tbl->fat_start, fat);
  176.     
  177.     /* Search for first match of file specification */
  178.     setdta(&dir_entry);
  179.     if (search_first(fcb) == 255) {
  180.         printf("No files match '%c:", 'A'+drive);
  181.         for (i=0; i<11; i++) {
  182.             if (fcb->file_name[i] != ' ')
  183.               putchar(fcb->file_name[i]);
  184.             if (i == 7)
  185.               putchar('.');
  186.         }
  187.         printf("'\n");
  188.     }
  189.     else {
  190.         /* Initialize and print headers */
  191.         num_files = num_contig = total_clusters = alt_total = 0;
  192.         size_total = 0L;
  193.         printf("Filename Ext    Bytes   Actual      ");
  194.         printf("Last Modified     Flag     Clusters\n");
  195.         printf("======== === ======== ========  ===");
  196.         printf("================  ====  =============\n");
  197.         
  198.         /* Loop over matched files */
  199.         do {
  200.             /* Print file name and extension */
  201.             for (i=0; i<11; i++) {
  202.                 putchar(dir_entry.body.filname[i]);
  203.                 if (i == 7)
  204.                   putchar(' ');
  205.             }
  206.             
  207.             
  208.             /* Print size form directory and actual size */
  209.             printf("%9ld", dir_entry.body.filsize);
  210.             size_total += dir_entry.body.filsize;
  211.             if (alt_drive != -1) {
  212.                 alt_total += dir_entry.body.filsize/alt_clsize;
  213.                 if (dir_entry.body.filsize % alt_clsize != 0)
  214.                   ++alt_total;
  215.             }
  216.             if (dir_entry.body.first_cluster != 0)
  217.               for (cluster_count = 0,
  218.                 cluster=dir_entry.body.first_cluster;
  219.                 cluster!=LAST_CLUSTER(twelve_bit_fat);
  220.                 cluster = fatval(twelve_bit_fat, cluster, fat))
  221.                cluster_count++;
  222.             else
  223.               cluster_count = 0;
  224.             total_clusters += cluster_count;
  225.             printf("%9ld  ", (long) cluster_count *
  226.               (long) (tbl->cluster_size+1) * (long) tbl->sector_size);
  227.             
  228.             /* Print creation date, time and flag settings */
  229.             dtoa(dir_entry.body.create_date, cre_date);
  230.             ttoa(dir_entry.body.create_time, cre_time);
  231.             printf("%s %s", cre_date, cre_time);
  232.             print_flags(dir_entry.body.attributes);
  233.             
  234.             /* Print cluster chaining information */
  235.             num_files++;
  236.             if(do_chain(dir_entry.body.first_cluster, fat, twelve_bit_fat))
  237.               num_contig++;
  238.         } while (search_next(fcb) != 255);
  239.         
  240.         /* Print totals and summary information */
  241.         printf("======== === ======== ========  ===");
  242.         printf("================  ====  =============\n");
  243.         printf("TOTALS      ");
  244.         printf("%9ld", size_total);
  245.         printf("%9ld\n", (long) total_clusters *
  246.           (long) (tbl->cluster_size+1) * (long) tbl->sector_size);
  247.         printf("\n\t%d Files, %d Contiguous, ",
  248.           num_files, num_contig);
  249.         printf("%d Noncontiguous\n", (num_files-num_contig));
  250.         printf("\tFiles use %d clusters @ %d bytes/cluster\n",
  251.           total_clusters, (tbl->cluster_size+1) * tbl->sector_size);
  252.         getdfs(drive, &avail, &total, §size);
  253.         printf("\t%lu bytes free\n", (long) avail *
  254.           (long) (tbl->cluster_size+1) * (long) sectsize);
  255.         
  256.         /* Show space needed on alt. drive (if requested) */
  257.         if (alt_drive != -1) {
  258.             printf("\n\tFiles would require %lu bytes ",
  259.               (long) alt_total * (long) alt_clsize);
  260.             printf("on drive %c\n", alt_drive+'A');
  261.             getdfs(alt_drive, &avail, &total, §size);
  262.             printf("\t%lu bytes free on drive %c\n",
  263.               (long) avail * (long) alt_clsize, alt_drive+'A');
  264.         }
  265.     }
  266. }
  267.  
  268. /* do_chain -- print chaining of clusters in FAT
  269. **        (Handles both 12 bit and 16 bit
  270. **        FAT entries.)
  271. */
  272. do_chain(start, fat, is12)
  273. unsigned start;
  274. unsigned char *fat;
  275. int is12;
  276. {
  277.     unsigned old_cluster, new_cluster;
  278.     int i, extent_size, is_contiguous;
  279.     is_contiguous = TRUE;
  280.     if (start >= 2) {
  281.         old_cluster = start;
  282.         extent_size = 1;
  283.         printf((is12 ? "    [%03x]":"  [%04x]"), old_cluster);
  284.         do {
  285.             if (extent_size == 0) {
  286.                 is_contiguous = FALSE;
  287.                 for (i=0; i<60; i++)
  288.                   putchar(' ');
  289.                   printf((is12 ? " [%03x]":"[%04x]"), old_cluster);
  290.                   extent_size++;
  291.             }
  292.             new_cluster = fatval(is12, old_cluster, fat);
  293.             if (new_cluster != (old_cluster + 1)) {
  294.                 if (extent_size > 1)
  295.                   printf((is12 ? "-[%03x]":"-[%04x]"), old_cluster);
  296.                 extent_size = 0;
  297.                 putchar('\n');
  298.             }
  299.             else
  300.               extent_size++;
  301.             old_cluster = new_cluster;
  302.         } while(old_cluster != LAST_CLUSTER(is12));
  303.     }
  304.     else
  305.       putchar('\n');
  306.     return(is_contiguous);
  307. }
  308.  
  309.