home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <dos.h>
- #include <malloc.h>
- #include <direct.h>
- #include <string.h>
-
- /* show -- This program prints an enhanced directory
- ** listing for a disk. The output resembles that
- ** from the DOS DIR command, but includes the
- ** following additional information for each file:
- **
- ** 1) The flag settings for the file. 'a' if the
- ** "archive" bit is set, 'h' if the "hidden"
- ** bit is set, 's' if the "system" bit is
- ** set and 'r' if the "read only" bit is set.
- **
- ** 2) The actual amount of space allocated for
- ** storage of the file, reflecting the number
- ** of clusters allocated to the file.
- **
- ** 3) The cluster chaining for the file. Cluster
- ** numbers are shown in hex. Gaps are shown
- ** by starting a new line.
- **
- ** Also displayed are totals for bytes in files,
- ** total bytes allocated to files, number of files,
- ** (broken down as contiguous and noncontiguous),
- ** number of clusters used, and bytes of free
- ** space remaining.
- **
- ** Usage: show [d:filename.ext [a:]]
- **
- ** If the drive specification d: is omitted, the
- ** current default drive is assumed. If the
- ** filename or extension are omitted, '*' is
- ** assumed.
- **
- ** If the alternate drive specification a: is given
- ** the program will compute the amount of space
- ** the specified files would require on this
- ** alternate drive along with the actual amount of
- ** space currently available on that drive.
- **
- ** Compiler: Microsoft C V3.0
- ** Options : /Zp (pack arrays)
- ** /Ze (support "far" extension)
- **
- ** External modules:
- ** absread()
- **
- ** Version 1.35 February 6, 1986
- **
- ** Glenn F. Roberts
- */
- #define TRUE 1
- #define FALSE 0
- #define MIN_VERSION 200 /* DOS 2.0 */
- #define MAX_VERSION 310 /* DOS 3.1 */
- #define MAX_CWD_LEN 63
-
- #include "structs.h"
- #include "dosfns.h"
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int ver;
- static struct ext_fcb fcb = {
- 0xFF,0,0,0,0,0,0,0,
- '?','?','?','?','?','?','?','?','?','?','?',
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- };
- static struct ext_fcb alt_fcb = {
- 0xFF,0,0,0,0,0,0,0,
- '?','?','?','?','?','?','?','?','?','?','?',
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- };
-
- ver = _osmajor*100+_osminor;
- if ((ver < MIN_VERSION) || (ver > MAX_VERSION))
- printf("Incorrect DOS version %d\n", ver);
- else if (!((--argc > 0) ?
- (parse(*++argv, &fcb.drive_id, 12) != 255) : TRUE))
- printf("Invalid drive specification\n");
- else if (!((--argc > 0) ?
- (parse(*++argv, &alt_fcb.drive_id, 1) != 255) : TRUE))
- printf("Invalid alternate drive\n");
- else {
- fcb.fcb_hdr.attrib =
- HIDDEN | ARCHIVE | SYSTEM | READ_ONLY;
- do_entry(&fcb, alt_fcb.drive_id-1);
- }
- }
-
- /* print_vname -- print volume name and
- ** current working directory.
- */
- print_vname(drive)
- int drive;
- {
- struct extended_entry dir_entry;
- static struct ext_fcb vol_fcb = {
- 0xFF,0,0,0,0,0,VOL_ENTRY,0,
- '?','?','?','?','?','?','?','?','?','?','?',
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- };
- int i, drive_save;
- char current_dir[MAX_CWD_LEN+1];
-
- printf("\tVolume in Drive %c is ", (drive + 'A'));
- setdta(&dir_entry);
- vol_fcb.drive_id = drive+1;
- if (search_first(&vol_fcb) != 255) {
- for (i=0; i<11; i++)
- putchar(dir_entry.body.filname[i]);
- putchar('\n');
- }
- else
- printf("Unlabeled\n");
- printf("\tDirectory of ");
- drive_save = current_drv();
- select_drv(drive);
- getcwd(current_dir, MAX_CWD_LEN);
- printf("%s\n\n", current_dir);
- select_drv(drive_save);
- }
-
- /* print_flags -- print ASCII indication of file
- ** flag settings.
- */
- print_flags(attrib)
- char attrib;
- {
- char str[7];
-
- strcpy(str, " ");
- if (attrib & ARCHIVE) str[2] = 'a';
- if (attrib & HIDDEN) str[3] = 'h';
- if (attrib & READ_ONLY) str[4] = 'r';
- if (attrib & SYSTEM) str[5] = 's';
- printf("%s", str);
- }
-
- /* do_entry -- print output for file specification
- ** as parsed in fcb.
- */
- do_entry(fcb, alt_drive)
- struct ext_fcb *fcb;
- int alt_drive;
- {
- unsigned cluster, avail, total, sectsize;
- int i, drive, num_files, num_contig, total_clusters;
- int twelve_bit_fat, cluster_count, alt_clsize, alt_total;
- long size_total, actual_total;
- struct extended_entry dir_entry;
- struct disk_table far *get_table(), far *tbl, far *alt_tbl;
- unsigned char *fat, cre_date[15], cre_time[15];
-
- /* Get target drive information */
- drive = (fcb->drive_id == 0) ? current_drv() : fcb->drive_id-1;
- print_vname(drive);
- tbl = get_table(drive);
- twelve_bit_fat = tbl->last_cluster < MAX_12BIT;
-
- /* If alternate drive given, look up drive info. */
- if (alt_drive != -1) {
- alt_tbl = get_table(alt_drive);
- alt_clsize = alt_tbl->sector_size * (alt_tbl->cluster_size+1);
- }
-
- /* Read File Allocation Table */
- fat = (unsigned char *) malloc(tbl->fat_size*tbl->sector_size);
- absread(drive, tbl->fat_size, tbl->fat_start, fat);
-
- /* Search for first match of file specification */
- setdta(&dir_entry);
- if (search_first(fcb) == 255) {
- printf("No files match '%c:", 'A'+drive);
- for (i=0; i<11; i++) {
- if (fcb->file_name[i] != ' ')
- putchar(fcb->file_name[i]);
- if (i == 7)
- putchar('.');
- }
- printf("'\n");
- }
- else {
- /* Initialize and print headers */
- num_files = num_contig = total_clusters = alt_total = 0;
- size_total = 0L;
- printf("Filename Ext Bytes Actual ");
- printf("Last Modified Flag Clusters\n");
- printf("======== === ======== ======== ===");
- printf("================= ==== =============\n");
-
- /* Loop over matched files */
- do {
- /* Print file name and extension */
- for (i=0; i<11; i++) {
- putchar(dir_entry.body.filname[i]);
- if (i == 7)
- putchar(' ');
- }
-
- /* Print size from directory and actual size */
- printf("%9ld", dir_entry.body.filsize);
- size_total += dir_entry.body.filsize;
- if (alt_drive != -1) {
- alt_total += dir_entry.body.filsize/alt_clsize;
- if (dir_entry.body.filsize % alt_clsize != 0)
- ++alt_total;
- }
- if (dir_entry.body.first_cluster != 0)
- for (cluster_count=0,
- cluster=dir_entry.body.first_cluster;
- cluster!=LAST_CLUSTER(twelve_bit_fat);
- cluster = fatval(twelve_bit_fat, cluster, fat))
- cluster_count++;
- else
- cluster_count = 0;
- total_clusters += cluster_count;
- printf("%9ld ", (long) cluster_count *
- (long) (tbl->cluster_size+1) * (long) tbl->sector_size);
-
- /* Print creation date, time and flag settings */
- dtoa(dir_entry.body.create_date, cre_date);
- ttoa(dir_entry.body.create_time, cre_time);
- printf("%s %s", cre_date, cre_time);
- print_flags(dir_entry.body.attributes);
-
- /* Print cluster chaining information */
- num_files++;
- if(do_chain(dir_entry.body.first_cluster, fat, twelve_bit_fat))
- num_contig++;
- } while (search_next(fcb) != 255);
-
- /* Print totals and summary information */
- printf("======== === ======== ======== ===");
- printf("================= ==== =============\n");
- printf("TOTALS ");
- printf("%9ld", size_total);
- printf("%9ld\n", (long) total_clusters *
- (long) (tbl->cluster_size+1) * (long) tbl->sector_size);
- printf("\n\t%d Files, %d Contiguous, ",
- num_files, num_contig);
- printf("%d Noncontiguous\n", (num_files-num_contig));
- printf("\tFiles use %d clusters @ %d bytes/cluster\n",
- total_clusters, (tbl->cluster_size+1) * tbl->sector_size);
- getdfs(drive, &avail, &total, §size);
- printf("\t%lu bytes free\n", (long) avail *
- (long) (tbl->cluster_size+1) * (long) sectsize);
-
- /* Show space needed on alt. drive (if requested) */
- if (alt_drive != -1) {
- printf("\n\tFiles would require %lu bytes ",
- (long) alt_total * (long) alt_clsize);
- printf("on drive %c\n", alt_drive + 'A');
- getdfs(alt_drive, &avail, &total, §size);
- printf("\t%lu bytes free on drive %c\n",
- (long) avail * (long) alt_clsize, alt_drive + 'A');
- }
- }
- }
-
- /* do_chain -- print chaining of clusters in FAT
- ** (Handles both 12 bit and 16 bit
- ** FAT entries.)
- */
- do_chain(start, fat, is12)
- unsigned start;
- unsigned char *fat;
- int is12;
- {
- unsigned old_cluster, new_cluster;
- int i, extent_size, is_contiguous;
-
- is_contiguous = TRUE;
- if (start >= 2) {
- old_cluster = start;
- extent_size = 1;
- printf((is12 ? " [%03x]":" [%04x]"), old_cluster);
- do {
- if (extent_size == 0) {
- is_contiguous = FALSE;
- for (i=0; i<60; i++)
- putchar(' ');
- printf((is12 ? " [%03x]":"[%04x]"), old_cluster);
- extent_size++;
- }
- new_cluster = fatval(is12, old_cluster, fat);
- if (new_cluster != (old_cluster + 1)) {
- if (extent_size > 1)
- printf((is12 ? "-[%03x]":"-[%04x]"), old_cluster);
- extent_size = 0;
- putchar('\n');
- }
- else
- extent_size++;
- old_cluster = new_cluster;
- } while (old_cluster != LAST_CLUSTER(is12));
- }
- else
- putchar('\n');
- return(is_contiguous);
- }
-