home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MAGAZINE / MISC / MAY86.ZIP / SHOW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-02-06  |  9.6 KB  |  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 prints an enhanced directory
  10. **          listing for a disk.  The output resembles that
  11. **          from the DOS DIR command, 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 noncontiguous),
  30. **          number of clusters used, and bytes of free
  31. **          space remaining.
  32. **
  33. **          Usage: show [d:filename.ext [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 V3.0
  47. **          Options :    /Zp    (pack arrays)
  48. **                       /Ze    (support "far" extension)
  49. **
  50. **          External modules:
  51. **                       absread()
  52. **
  53. **          Version 1.35     February 6, 1986
  54. **
  55. **          Glenn F. Roberts
  56. */
  57. #define TRUE 1
  58. #define FALSE 0
  59. #define MIN_VERSION 200     /* DOS 2.0 */
  60. #define MAX_VERSION 310     /* DOS 3.1 */
  61. #define MAX_CWD_LEN 63
  62.  
  63. #include "structs.h"
  64. #include "dosfns.h"
  65.  
  66. main(argc, argv)
  67. int argc;
  68. char *argv[];
  69. {
  70.   int ver;
  71.   static struct ext_fcb fcb = {
  72.     0xFF,0,0,0,0,0,0,0,
  73.     '?','?','?','?','?','?','?','?','?','?','?',
  74.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  75.   };
  76.   static struct ext_fcb alt_fcb = {
  77.     0xFF,0,0,0,0,0,0,0,
  78.     '?','?','?','?','?','?','?','?','?','?','?',
  79.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  80.   };
  81.  
  82.   ver = _osmajor*100+_osminor;
  83.   if ((ver < MIN_VERSION) || (ver > MAX_VERSION))
  84.     printf("Incorrect DOS version %d\n", ver);
  85.   else if (!((--argc > 0) ?
  86.       (parse(*++argv, &fcb.drive_id, 12) != 255) : TRUE))
  87.     printf("Invalid drive specification\n");
  88.   else if (!((--argc > 0) ?
  89.       (parse(*++argv, &alt_fcb.drive_id, 1) != 255) : TRUE))
  90.     printf("Invalid alternate drive\n");
  91.   else {
  92.     fcb.fcb_hdr.attrib =
  93.         HIDDEN | ARCHIVE | SYSTEM | READ_ONLY;
  94.     do_entry(&fcb, alt_fcb.drive_id-1);
  95.   }
  96. }
  97.  
  98. /*  print_vname -- print volume name and
  99. **                 current working directory.
  100. */
  101. print_vname(drive)
  102. int drive;
  103. {
  104.   struct extended_entry dir_entry;
  105.   static struct ext_fcb vol_fcb = {
  106.     0xFF,0,0,0,0,0,VOL_ENTRY,0,
  107.     '?','?','?','?','?','?','?','?','?','?','?',
  108.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  109.   };
  110.   int i, drive_save;
  111.   char current_dir[MAX_CWD_LEN+1];
  112.  
  113.   printf("\tVolume in Drive %c is ", (drive + 'A'));
  114.   setdta(&dir_entry);
  115.   vol_fcb.drive_id = drive+1;
  116.   if (search_first(&vol_fcb) != 255) {
  117.     for (i=0; i<11; i++)
  118.       putchar(dir_entry.body.filname[i]);
  119.     putchar('\n');
  120.   }
  121.   else
  122.     printf("Unlabeled\n");
  123.   printf("\tDirectory of ");
  124.   drive_save = current_drv();
  125.   select_drv(drive);
  126.   getcwd(current_dir, MAX_CWD_LEN);
  127.   printf("%s\n\n", current_dir);
  128.   select_drv(drive_save);
  129. }
  130.  
  131. /*  print_flags -- print ASCII indication of file
  132. **                 flag settings.
  133. */
  134. print_flags(attrib)
  135. char attrib;
  136. {
  137.   char str[7];
  138.  
  139.   strcpy(str, "      ");
  140.   if (attrib & ARCHIVE)   str[2] = 'a';
  141.   if (attrib & HIDDEN)    str[3] = 'h';
  142.   if (attrib & READ_ONLY) str[4] = 'r';
  143.   if (attrib & SYSTEM)    str[5] = 's';
  144.   printf("%s", str);
  145. }
  146.  
  147. /*  do_entry -- print output for file specification
  148. **              as parsed in fcb.
  149. */
  150. do_entry(fcb, alt_drive)
  151. struct ext_fcb *fcb;
  152. int alt_drive;
  153. {
  154.   unsigned cluster, avail, total, sectsize;
  155.   int i, drive, num_files, num_contig, total_clusters;
  156.   int twelve_bit_fat, cluster_count, alt_clsize, alt_total;
  157.   long size_total, actual_total;
  158.   struct extended_entry dir_entry;
  159.   struct disk_table far *get_table(), far *tbl, far *alt_tbl;
  160.   unsigned char *fat, cre_date[15], cre_time[15];
  161.  
  162.   /* Get target drive information */
  163.   drive = (fcb->drive_id == 0) ? current_drv() : fcb->drive_id-1;
  164.   print_vname(drive);
  165.   tbl = get_table(drive);
  166.   twelve_bit_fat = tbl->last_cluster < MAX_12BIT;
  167.  
  168.   /* If alternate drive given, look up drive info. */
  169.   if (alt_drive != -1) {
  170.     alt_tbl = get_table(alt_drive);
  171.     alt_clsize = alt_tbl->sector_size * (alt_tbl->cluster_size+1);
  172.   }
  173.  
  174.   /* Read File Allocation Table */
  175.   fat = (unsigned char *) malloc(tbl->fat_size*tbl->sector_size);
  176.   absread(drive, tbl->fat_size, tbl->fat_start, fat);
  177.  
  178.   /* Search for first match of file specification */
  179.   setdta(&dir_entry);
  180.   if (search_first(fcb) == 255) {
  181.     printf("No files match '%c:", 'A'+drive);
  182.     for (i=0; i<11; i++) {
  183.       if (fcb->file_name[i] != ' ')
  184.         putchar(fcb->file_name[i]);
  185.       if (i == 7)
  186.         putchar('.');
  187.     }
  188.     printf("'\n");
  189.   }
  190.   else {
  191.     /* Initialize and print headers */
  192.     num_files = num_contig = total_clusters = alt_total = 0;
  193.     size_total = 0L;
  194.     printf("Filename Ext    Bytes   Actual      ");
  195.     printf("Last Modified     Flag    Clusters\n");
  196.     printf("======== === ======== ========  ===");
  197.     printf("=================  ====  =============\n");
  198.  
  199.     /* Loop over matched files */
  200.     do {
  201.       /* Print file name and extension */
  202.       for (i=0; i<11; i++) {
  203.         putchar(dir_entry.body.filname[i]);
  204.         if (i == 7)
  205.           putchar(' ');
  206.       }
  207.  
  208.       /* Print size from 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.  
  280.   is_contiguous = TRUE;
  281.   if (start >= 2) {
  282.     old_cluster = start;
  283.     extent_size = 1;
  284.     printf((is12 ? "   [%03x]":"  [%04x]"), old_cluster);
  285.     do {
  286.       if (extent_size == 0) {
  287.         is_contiguous = FALSE;
  288.         for (i=0; i<60; i++)
  289.           putchar(' ');
  290.         printf((is12 ? " [%03x]":"[%04x]"), old_cluster);
  291.         extent_size++;
  292.       }
  293.       new_cluster = fatval(is12, old_cluster, fat);
  294.       if (new_cluster != (old_cluster + 1)) {
  295.         if (extent_size > 1)
  296.           printf((is12 ? "-[%03x]":"-[%04x]"), old_cluster);
  297.         extent_size = 0;
  298.         putchar('\n');
  299.       }
  300.       else
  301.         extent_size++;
  302.       old_cluster = new_cluster;
  303.     } while (old_cluster != LAST_CLUSTER(is12));
  304.   }
  305.   else
  306.     putchar('\n');
  307.   return(is_contiguous);
  308. }
  309.