mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-26 18:04:07 +00:00
229 lines
7.2 KiB
C
229 lines
7.2 KiB
C
#define VN "1.0 02/11/83"
|
||
/* SPACE - This utility displays a map showing on the amount of space
|
||
(expressed as relative percentages) occupied in each user number
|
||
for each logical disk). It also shows the relative amount of space
|
||
free. */
|
||
|
||
#include <LIBRARY.H>
|
||
|
||
struct _dirpb dir_pb; /* directory management parameter block */
|
||
struct _dir *dir_entry; /* pointer to directory entry */
|
||
struct _scb scb; /* search control block */
|
||
struct _dpb dpb; /* CP/M's disk parameter block */
|
||
|
||
char file_name[20]; /* formatted for display : un/d:FILENAME.TYP */
|
||
|
||
short cur_disk; /* current logical disk at start of program
|
||
NZ = show map of number of files */
|
||
int count; /* used to access the allocation block numbers
|
||
in each directory entry */
|
||
int user; /* used to access the disk map when calculating */
|
||
|
||
/* The array below is used to tabulate the results for each
|
||
disk drive, and for each user number on the drive.
|
||
In addition, two extra "users" have been added for "Free"
|
||
and "Used" values.
|
||
*/
|
||
unsigned disk_map[16][18]; /* Disk A -> P, Users 0 -> 15, Free, Used */
|
||
#define USED_COUNT 16 /* "user" number for Used entities */
|
||
#define FREE_COUNT 17 /* "user" number for Free entities */
|
||
|
||
|
||
main(argc,argv)
|
||
short argc; /* argument count */
|
||
char *argv[]; /* argument vector (pointer to an array of chars) */
|
||
{
|
||
|
||
printf("\nSPACE Version %s (Library %s)",VN,LIBVN);
|
||
chk_use(argc); /* check usage */
|
||
cur_disk = bdos(GETDISK); /* get current default disk */
|
||
|
||
dm_clr(disk_map); /* reset disk map */
|
||
|
||
ssetscb(scb,argv[1]); /* special version : set disks,
|
||
name, type */
|
||
|
||
for (scb.scb_disk = 0; /* starting with logical disk A: */
|
||
scb.scb_disk < 16; /* until logical disk P: */
|
||
scb.scb_disk++) /* move to next logical disk */
|
||
{
|
||
|
||
/* check if current disk has been selected for search */
|
||
if (!(scb.scb_adisks & (1 << scb.scb_disk)))
|
||
continue; /* no - so bypass this disk */
|
||
|
||
printf("\nSearching disk : %c",(scb.scb_disk + 'A'));
|
||
|
||
dir_pb.dp_disk = scb.scb_disk; /* set to disk to be searched*/
|
||
|
||
/* set the directory to "closed", and force the get_nde
|
||
function to open it. */
|
||
dir_pb.dp_open = 0;
|
||
|
||
/* while not at the end of the directory, set a pointer
|
||
to the next entry in the directory */
|
||
while (dir_entry = get_nde(dir_pb))
|
||
{
|
||
if (dir_entry -> de_userno == 0xE5)
|
||
continue; /* bypass inactive entries */
|
||
|
||
for (count = 0; /* start with the first alloc. block */
|
||
count < dir_pb.dp_nabpde; /* for number of alloc. blks per dir. entry */
|
||
count++)
|
||
{
|
||
if (dir_pb.dp_nabpde == 8) /* assume 8 2-byte numbers */
|
||
{
|
||
disk_map[scb.scb_disk][dir_entry -> de_userno]
|
||
+= (dir_entry -> _dirab.de_long[count] > 0 ? 1 : 0);
|
||
}
|
||
else /* assume 16 1-byte numbers */
|
||
{
|
||
disk_map[scb.scb_disk][dir_entry -> de_userno]
|
||
+= (dir_entry -> _dirab.de_short[count] > 0 ? 1 : 0);
|
||
}
|
||
} /* all allocation blocks processed */
|
||
} /* end of directory for this disk */
|
||
|
||
|
||
/* Compute the storage used by multiplying the number of
|
||
allocation blocks counted by the number of Kbytes in
|
||
each allocation block. */
|
||
|
||
for (user = 0; /* start with user 0 */
|
||
user < 16; /* end with user 15 */
|
||
user ++) /* move to next user number */
|
||
{
|
||
/* compute size occupied in Kbytes */
|
||
disk_map[scb.scb_disk][user] *= dir_pb.dp_absize;
|
||
/* build up sum for this disk */
|
||
disk_map[scb.scb_disk][USED_COUNT] += disk_map[scb.scb_disk][user];
|
||
}
|
||
|
||
/* free space = (# of alloc. blks * # of kbyte per blk)
|
||
- used Kbytes
|
||
- (directory entries * 32) / 1024 ... or divide by 32 */
|
||
disk_map[scb.scb_disk][FREE_COUNT] = (dir_pb.dp_nab * dir_pb.dp_absize)
|
||
- disk_map[scb.scb_disk][USED_COUNT]
|
||
- (dir_pb.dp_nument >> 5); /* same as / 32 */
|
||
} /* all disks processed */
|
||
|
||
|
||
printf("\n Numbers show space used in kilobytes.");
|
||
printf("\n --- User Numbers --- Space (Kb)");
|
||
|
||
dm_disp(disk_map,scb.scb_adisks); /* display disk map */
|
||
|
||
|
||
bdos(SETDISK,cur_disk); /* reset to current disk */
|
||
}
|
||
|
||
ssetscb(scb,ldisks) /* special version of - set search control block */
|
||
/* This function sets up a search control block according
|
||
to just the logical disks specified. The disk are specified as
|
||
a single string of characters without any separators. An
|
||
asterisk means "all disks". For example -
|
||
|
||
ABGH (disks A:, B:, G: and H: )
|
||
* (all disks for which SELDSK has tables)
|
||
|
||
It sets the bit map according to which disks should be searched.
|
||
For each selected disk, it checks to see if an error is generated
|
||
when selecting the disk (i.e. if there are disk tables in the BIOS
|
||
for the disk).
|
||
The file name, type and extent number are all set to '?' to match
|
||
all possible entries in the directory. */
|
||
|
||
/* Entry Parameters */
|
||
struct _scb *scb; /* pointer to search control block */
|
||
char *ldisks; /* pointer to the logical disks */
|
||
|
||
/* Exit Parameters
|
||
None.
|
||
*/
|
||
{
|
||
int disk; /* disk number currently being checked */
|
||
unsigned adisks; /* bit map for active disks */
|
||
|
||
adisks = 0; /* assume no disks to search */
|
||
|
||
if (*ldisks) /* some values specified */
|
||
{
|
||
if (*ldisks == '*') /* check if "all disks" */
|
||
{
|
||
adisks = 0xFFFF; /* set all bits */
|
||
}
|
||
else /* set specific disks */
|
||
{
|
||
while(*ldisks) /* until end of disks reached */
|
||
{
|
||
/* build the bit map by getting the next disk
|
||
id. (A - P), converting it to a number
|
||
in the range 0 - 15, and shifting a 1-bit
|
||
left that many places and OR-ing it into
|
||
the current active disks.
|
||
*/
|
||
adisks |= 1 << (toupper(*ldisks) - 'A');
|
||
++ldisks; /* move to next character */
|
||
}
|
||
}
|
||
}
|
||
else /* use only current default disk */
|
||
{
|
||
/* set just the bit corresponding to the current disk */
|
||
adisks = 1 << bdos(GETDISK);
|
||
}
|
||
|
||
/* set the user number, file name, type and extent to '?'
|
||
so that all active directory entries will match */
|
||
/* 0123456789012 */
|
||
strcpy(&scb -> scb_userno,"?????????????");
|
||
|
||
/* Make calls to the BIOS SELDSK routine to make sure that
|
||
all of the active disk drives indeed do have disk tables
|
||
for them in the BIOS. If they don't, turn off the corresponding
|
||
bits in the bit map. */
|
||
|
||
|
||
for (disk = 0; /* start with disk A: */
|
||
disk < 16; /* until disk P: */
|
||
disk++) /* use next disk */
|
||
{
|
||
if ( !((1 << disk) & adisks) ) /* avoid unnecessary selects */
|
||
continue;
|
||
if (biosh(SELDSK,disk) == 0) /* make BIOS SELDSK call */
|
||
{ /* returns 0 if invalid disk */
|
||
/* turn OFF corresponding bit in mask
|
||
by ANDing it with bit mask having
|
||
all the other bits set = 1. */
|
||
adisks &= ((1 << disk) ^ 0xFFFF);
|
||
}
|
||
}
|
||
|
||
scb -> scb_adisks = adisks; /* set bit map in scb */
|
||
|
||
} /* end ssetscb */
|
||
|
||
|
||
|
||
chk_use(argc) /* check usage */
|
||
/* This function checks that the correct number of
|
||
parameters has been specified, outputting instructions
|
||
if not. */
|
||
|
||
/* Entry Parameter */
|
||
int argc; /* Count of the number of arguments on the command line */
|
||
{
|
||
|
||
/* The minimum value of argc is 1 (for the program name itself),
|
||
so argc is always one greater than the number of parameters
|
||
on the command line */
|
||
|
||
if (argc != 2)
|
||
{
|
||
printf("\nUsage :");
|
||
printf("\n\tSPACE * (All disks)");
|
||
printf("\n\tSPACE ABCD..OP (Selected Disks)");
|
||
exit();
|
||
}
|
||
} /* end chk_use */
|
||
|