home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
dirutl
/
dskparm.arc
/
SHOW.C
< prev
next >
Wrap
Text File
|
1987-12-26
|
9KB
|
309 lines
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <dos.h>
#include <malloc.h>
#include <direct.h>
#include <string.h>
/* show -- This program rints an enhanced directory
** listing for a disk. The output resembles that
** from the DOS DIR comand, 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 noncontigous),
** number of clusters used, and bytes of free
** space remaining.
**
** Usage: show [d:filename.exe [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 V4.0
** Options: /Zp (pack arrays) (V3.0 requires /Ze)
**
** External modules:
** absread()
**
** Version 1.33 February 6, 1986
**
** Glenn F. Roberts
*/
#define TRUE 1
#define FALSE 0
#define MIN_VERSION 200 /* DOS 2.0 */
#define MAX_VERSION 330 /* DOS 3.3 */
#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 form 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);
}