pete@octopus.UUCP (Pete Holzmann) (01/06/89)
I ran into an interesting problem today. I wonder if anybody out there has dealt with it already? Please attempt to email answers since this is pretty esoteric. I'll summarize the solution to the net (if one is found!) I have a program that wants to test for remaining space in a temp hard disk area before creating some mongo files. The normal disk-space DOS (and MS/Turbo C) routines return remaining space on the current *drive*, but not for the current *directory*. This is not important in pre-JOIN days, but now things can get messed up: C: has 8 MB free C:\foo (current directory, where the user wants to put their stuff) has 2 MB free (drive D: is JOINed to C:\foo) The DOS call tells me I have 8 MB to play with. I try to use it and get blown away 'cuz really there are only 2! Anybody know how to resolve this? I can't even find anything that shows me if/how the current directory relates to JOINed disk drives! Thanks! Pete -- OOO __| ___ Peter Holzmann, Octopus Enterprises OOOOOOO___/ _______ USPS: 19611 La Mar Court, Cupertino, CA 95014 OOOOO \___/ UUCP: {hpda,pyramid}!octopus!pete ___| \_____ Phone: 408/996-7746
nelson@sun.soe.clarkson.edu (Russ Nelson) (01/07/89)
In article <467@octopus.UUCP> pete@octopus.UUCP (Pete Holzmann) writes: I have a program that wants to test for remaining space in a temp hard disk area before creating some mongo files. The normal disk-space DOS (and MS/Turbo C) routines return remaining space on the current *drive*, but not for the current *directory*. Anybody know how to resolve this? I can't even find anything that shows me if/how the current directory relates to JOINed disk drives! Seek and ye shall find! I just finished writing a program that works like Unix's df(1). It searches through the drive tables to see which are join'ed and which are subst'ed, and gets the correct free space. Df will compile under TC 1.0, TC 1.5, and TC 2.0. I imagine that it will not be difficult to port to MSC. Since it's short and illustrates a solution to the problem of disk space for join'ed and subst'ed drives as well as identifying those drives, I'll include it right here: /* df - dump filesystems. * * Copyright 1988 By Russell Nelson. Don't try to make money off of it, and * don't pretend that you wrote it. * * Compile with: tcc -mc df.c * * usage: df [drive letters] * (The default drives to dump are all existing drives, unless an * environment variable called 'df' exists, in which case only the drives * specified by the variable are dumped. For example, I use "DF=acd" because * I have two hard disks. * * Compu$erve: 70441,205 * GEnie: BH01 * Internet: nelson@clutx.clarkson.edu * BITNET: NELSON@CLUTX * Fido/Opus: Russ Nelson@1:260/360 */ #include <stdio.h> #include <dos.h> #include <dir.h> #include <string.h> #include <alloc.h> #include <ctype.h> #include <stdlib.h> #define DOS3 1 /* this program requires DOS 3 */ /* the following is undocumented */ struct drive_info { char current_path[64+2+1]; int flags; /* flags: */ #define SUBST 0x1000 #define JOIN 0x2000 #define PHYS 0x4000 char far *disk_block; int current_track; /* ??? Current track or block? -1 if never accessed. */ char far *bar; /* ??? I see -1 always */ unsigned baz; /* ??? I see 2 always */ }; /* the following is undocumented */ struct list_of_lists { unsigned first_mcb; char far *first_disk_block; char far *first_dos_file; char far *clock_driver; char far *con_driver; #ifdef DOS2 char drive_count; /* Number of logical drives in system */ unsigned bytes_per_block; /* Maximum bytes/block of any block device */ unsigned foo,bar; /* ??? */ #endif #ifdef DOS3 unsigned bytes_per_block; /* Maximum bytes/block of any block device */ char far *first_disk_buffer; /* Pointer to first disk buffer */ struct drive_info far *first_drive; /* Pointer to array of drive info: */ char far *fcb_table; /* Pointer to FCB table (if CONFIG.SYS contains FCBS=) */ unsigned fcb_size; /* Size of FCB table */ unsigned char block_devices; /* Number of block devices */ unsigned char lastdrive; /* Value of LASTDRIVE command in CONFIG.SYS (default 5) */ #endif /* NUL device driver appears here */ } *list_ptr; /* find a volume label. Search in subdirectory if the disk is mounted there. */ char *volume_name(int i, char *mounted) { struct ffblk ffblk; char root[64]; if (*mounted) sprintf(root, "%s\\*.*", mounted); else sprintf(root, "%c:\\*.*", 'A' + i); if (!findfirst(root, &ffblk, FA_LABEL)) { char *dot = strchr(ffblk.ff_name, '.'); if (dot) strcpy(dot, dot+1); return ffblk.ff_name; } else return(""); } /* given a list of drives, enable those drives */ set_drives(char *drives, char *specifier) { char *drive_ptr; for (drive_ptr = specifier; *drive_ptr; ) { if (drive_ptr[1] == '-' && tolower(drive_ptr[2]) >= tolower(drive_ptr[0])) { memset(&drives[tolower(drive_ptr[0]) - 'a'], 1, tolower(drive_ptr[2]) - tolower(drive_ptr[0]) + 1); drive_ptr+=3; } else if (isalpha(*drive_ptr)) { drives[tolower(*drive_ptr) - 'a'] = 1; drive_ptr++; } else drive_ptr++; } } main(int argc, char *argv[]) { int i; char *dskbuf; char drives[64], *drive_ptr; /* enable only the drives that we want */ memset(drives, 0, sizeof(drives)); if (argc == 1 && (drive_ptr = getenv("DF")) != NULL) set_drives(drives, drive_ptr); else if (argc == 1) memset(drives, 1, sizeof(drives)); else set_drives(drives, argv[1]); /* get MS-LOSS's list of lists (undocumented) */ _AH = 0x52; geninterrupt(0x21); list_ptr = MK_FP(_ES, _BX - 2); /* ensure that we have a buffer that's big enough for any drive. */ dskbuf = malloc(list_ptr->bytes_per_block); printf( " block total kbytes kbytes percent\n" "disk size kbytes used free used volume mount\n"); for (i = 0; i < list_ptr->lastdrive; i++) if (drives[i]) { struct drive_info *drive_ptr = &(list_ptr->first_drive[i]); struct dfree dtable; unsigned int block_size, percent; unsigned long total, used, free; char *mount_point; printf(" %c:", 'A' + i); if (drive_ptr->flags & SUBST) { printf(" Subsituting for %s\n", drive_ptr->current_path); } else if (absread(i, 1, 0, dskbuf) < 0) { printf(" %40s[Not Ready]\n", ""); } else { getdfree(i+1, &dtable); mount_point = drive_ptr->flags & JOIN?drive_ptr->current_path:""; block_size = dtable.df_bsec * dtable.df_sclus; total = (long)dtable.df_total * (long)block_size; used = ((long)dtable.df_total - (long)dtable.df_avail) * (long)block_size; free = (long)dtable.df_avail * (long)block_size; percent = (long)(dtable.df_total - dtable.df_avail) * 100L / (long)dtable.df_total; printf("%6u %7lu %7lu %7lu %6u%% %-12s %s\n", block_size, total / 1024L, used / 1024L, free / 1024L, percent, volume_name(i, mount_point), mount_point); } } } -- --russ (nelson@clutx [.bitnet | .clarkson.edu]) "I saved the whales!" - Rebecca L. Nelson, 3.5 years old, on receiving her Christmas present of a whale "adoption" certificate. Bless her liberal heart.