home *** CD-ROM | disk | FTP | other *** search
- /*
- * du.c:
- *
- * `Du' is a disk usage utility which computes the diskusage of
- * all the files in a directory and it's subdirectories.
- *
- * This utility is comparable with the UNIX du program.
- *
- * Usage: du [-s] [-a] [d:path ...]
- *
- * Option -s (/s) does not show subdirectories (short listing).
- * Option -a (/a) shows size of all the files.
- *
- * Copyright: Tom Vijlbrief, Baarn, The Netherlands
- * Date: Fri May 8 13:53:29 GMT+1:00 1987
- *
- * This program may be distributed freely for non commercial purposes
- * and with this Copyright notice unchanged.
- */
-
- /*
- * Compilation must be performed with structure packing and larger stack:
- * Microsoft C 4.00: -Zp -F2000
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <dos.h>
- #include <io.h>
- #include <direct.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #define BLOCK_SIZE 512
- #define ALL_FILES (0x1 | 0x2 | 0x4 | 0x10 |0x20)
- #define DIRECTORIES (0x10)
-
- #define NAME_LEN 8
- #define EXT_LEN 3
-
- #define MAX_CWD 256
-
- typedef unsigned char byte;
-
- typedef struct {
- byte FF;
- byte zero_5[5];
- byte attribute;
- byte drive;
- char name[NAME_LEN];
- char extension[EXT_LEN];
- unsigned cur_block;
- unsigned rec_size;
- unsigned fs_low;
- unsigned fs_high;
- unsigned date;
- byte unused2[10];
- byte cur_record;
- unsigned ran_low;
- unsigned ran_high;
- } ext_fcb;
-
- char *get_first(char *, int, ext_fcb *);
- char *get_next(ext_fcb *);
- long scan();
-
-
- byte sector[BLOCK_SIZE];
-
- int cluster_size;
-
- int a_flag;
- int s_flag;
- int in_tree;
-
- ext_fcb return_fcb;
-
- main(argc, argv)
-
- int argc;
- char *argv[];
- {
- char *option_p;
- static char cur_cwd[MAX_CWD];
- int drive_nr;
- int cur_drive;
-
- while (argc > 1) {
- option_p= *++argv;
-
- if (*option_p == '-' || *option_p == '/') {
- for (option_p++; *option_p; option_p++) {
- switch (*option_p) {
- case 'a':
- a_flag++;
- break;
- case 's':
- s_flag++;
- break;
- default:
- fprintf(stderr,
- "Unknown option: %c\n", *option_p);
- fprintf(stderr,
- "Usage: du [-s] [-a] [d:path ...]\n");
- exit(1);
- }
- }
- argc--;
- } else
- break;
- }
-
- if (argc == 1) {
- cluster_size= comp_cluster(get_drive());
- scan();
- } else {
- for (; argc > 1; argc--, argv++) {
- cur_drive= get_drive();
- getcwd(cur_cwd, MAX_CWD - 1);
- if ((*argv)[1] == ':')
- set_drive(tolower((*argv)[0]) - 'a');
- if (chdir(*argv) != 0) {
- perror(*argv);
- set_drive(cur_drive);
- continue;
- }
- cluster_size= comp_cluster(get_drive());
- scan();
- set_drive(cur_drive);
- if (chdir(cur_cwd) != 0) {
- perror(cur_cwd);
- exit(1);
- }
-
- in_tree= 0;
- }
- }
- }
-
-
- static struct stat the_stat;
- static char cwd[MAX_CWD];
-
- long scan()
- {
- char *p;
- long file_size;
- long disk_use;
- int tree_flag;
- ext_fcb the_fcb;
- char pattern[NAME_LEN + EXT_LEN + 2];
-
- tree_flag= in_tree;
- disk_use= 0;
-
- strcpy(pattern, "????????.???");
-
- p= get_first(pattern, ALL_FILES, &the_fcb);
- for (; p != NULL; p= get_next(&the_fcb)) {
- if (strcmp(p, ".. . ") == 0
- || strcmp(p, ". . ") == 0)
- continue;
-
- if (stat(p, &the_stat) != 0) {
- perror(p);
- exit(1);
- }
-
- if (the_stat.st_mode & S_IFDIR) {
- if (a_flag) {
- printf("%s\n", p);
- printf("========================\n");
- }
- chdir(p);
- in_tree= 1;
- disk_use+= scan();
- chdir("..");
- } else {
- disk_use+= ((file_size= the_stat.st_size) + (cluster_size - 1))
- / cluster_size * cluster_size;
- if (a_flag) {
- printf("%s: %10ld\n", p, file_size);
- }
- }
- }
-
- if (a_flag)
- printf("========================\n");
- if (!s_flag || !tree_flag)
- printf("Disk Usage : %10ld (%s)\n", disk_use,
- getcwd(cwd, MAX_CWD - 1));
- if (a_flag)
- printf("\n");
-
- return(disk_use);
- }
-
-
- /*
- * get_first returns the first_name in a directory matching the
- * pattern (e.g. ????????.OBJ) and attribute
- */
-
- char *get_first (pattern, attribute, fcb_p)
-
- char *pattern;
- int attribute;
- ext_fcb *fcb_p;
- {
- set_dta(&return_fcb);
-
- strncpy(fcb_p->name, pattern, NAME_LEN);
- strncpy(fcb_p->extension, pattern + NAME_LEN + 1, EXT_LEN);
- fcb_p->attribute= attribute;
- fcb_p->FF= 0xFF;
- fcb_p->drive= get_drive() + 1;
-
- if ((bdos(0x11, (int) fcb_p, 0) & 0xFF) == 0) {
- strncpy(pattern, return_fcb.name, NAME_LEN);
- strncpy(pattern + NAME_LEN + 1, return_fcb.extension, EXT_LEN);
- return(pattern);
- } else
- return(NULL);
- }
-
-
- char *get_next(fcb_p)
-
- ext_fcb *fcb_p;
- {
- static char pattern[]= "12345678.123";
-
- set_dta(&return_fcb);
-
- if ((bdos(0x12, (int) fcb_p, 0) & 0xFF) == 0) {
- strncpy(pattern, return_fcb.name, NAME_LEN);
- strncpy(pattern + NAME_LEN + 1, return_fcb.extension, EXT_LEN);
- pattern[NAME_LEN + EXT_LEN + 1]= '\0';
- return(pattern);
- } else {
- return(NULL);
- }
- }
-
-
- /*
- * `set_drive' changes the current drive. (A = 0, etc).
- */
- int set_drive(drive_nr)
-
- int drive_nr;
- {
- return(bdos(0xE, drive_nr, 0) & 0xFF);
- }
-
- /*
- * `get_drive' returns the number of the current drive. (A = 0, etc).
- */
- int get_drive()
-
- {
- return(bdos(0x19, 0, 0) & 0xFF);
- }
-
-
-
- set_dta(p)
-
- ext_fcb *p;
- {
- return(bdos(0x1A, (int) p, 0) & 0xFF);
- }
-
-
-
- #define DISK 0x13
- #define READ_SECT 0x2
- #define RESET_DISK 0x0
-
- #define FLOP_RETRIES 3
-
- int readsect(buffer, drive, head, cyl, sector, n_sectors)
-
- char *buffer;
- unsigned int drive;
- unsigned int head;
- unsigned int cyl;
- unsigned int sector;
- unsigned int n_sectors;
- {
- int result;
- int retries;
- int max_retries;
- union REGS inregs,
- outregs;
- struct SREGS segregs;
-
- segread(&segregs);
- segregs.es= segregs.ds;
-
- if (drive < 0x80)
- max_retries= FLOP_RETRIES;
- else
- max_retries= 1;
-
- for (retries= 0; retries < max_retries; retries++) {
- if (drive < 0x80) {
- inregs.h.ah= RESET_DISK;
- inregs.h.dl= drive;
- int86(DISK, &inregs, &outregs);
- }
-
- inregs.h.ah= READ_SECT;
- inregs.x.bx= (unsigned) buffer;
- inregs.h.dl= drive;
- inregs.h.dh= head;
- inregs.h.ch= cyl;
- inregs.h.cl= sector | ((cyl & ~0xFF) >> 2);
- inregs.h.al= n_sectors;
-
- result= (unsigned) int86x(DISK, &inregs, &outregs, &segregs) >> 8;
-
- if (outregs.x.cflag)
- continue;
- else
- break;
- }
- if (retries == max_retries)
- return(-result);
- else
- return(0);
- }
-
-
-
- int comp_cluster(drive_nr)
-
- int drive_nr;
- {
- int nr_sectors;
- int head_nr;
- int high_head;
- int sector_nr;
-
- if (drive_nr > 1)
- drive_nr+= 0x80 - 2;
-
- high_head= max_head(drive_nr);
-
- for (head_nr= 0; head_nr <= high_head; head_nr++) {
- for (sector_nr= 1; sector_nr <= 8; sector_nr++) {
- if (readsect(sector, drive_nr, head_nr, 0, sector_nr, 1) != 0) {
- fprintf(stderr, "Cannot read bootblock from disk\n");
- exit(1);
- }
- if (sector[0] == 0xEB)
- break;
- }
- if (sector[0] == 0xEB)
- break;
- }
- if (sector_nr > 8 || (nr_sectors= sector[13]) > 16) {
- nr_sectors= 4;
- fprintf(stderr,
- "Unknown bootblock, clustersize of 4 sectors assumed\n");
- }
- if (nr_sectors == 0)
- nr_sectors= 2;
- return(nr_sectors * BLOCK_SIZE);
- }
-
-
-
- #define GET_PARAM 0x8
-
- int max_head(drive)
-
- unsigned int drive;
- {
- union REGS inregs,
- outregs;
-
- inregs.h.ah= GET_PARAM;
- inregs.h.dl= drive;
-
- int86(DISK, &inregs, &outregs);
-
- if (outregs.x.cflag)
- return(0);
- else
- return(outregs.h.dh);
- }
-