home *** CD-ROM | disk | FTP | other *** search
- /*
- * DF - report disk space Ver. 1.1
- *
- * COPYRIGHT (C) 1989 by Urs Zurbuchen
- * ALL RIGHTS RESERVED
- *
- * You are granted to the right to copy and
- * distribute this program via any means
- * as long as you don't remove this notice.
- *
- * However, you are specifically prohibited
- * from charging, requesting any donations,
- * and from distributing it with commercial
- * products without prior written permission.
- *
- * ------------------------------------------------------------
- *
- * Displays a space usage statistic for all known drives in the
- * systems. For join'ed drives their real free space is reported.
- * Floppy sizes are only reported on request and if there is really
- * a floppy in the drive. If there is none, the program continues
- * without an error message.
- *
- * Example:
- * C\:> df -f
- * Total space Free space Drive
- * 362'496 131'072 36% a:
- * 2'060'288 1'155'072 56% c:
- * 40'607'744 8'216'576 20% d:
- * 67'051'520 5'554'176 8% e:
- * 12'976'128 7'417'856 57% f:
- * 518'912 518'912 100% g:
- *
- *
- * Date: 16 January 1988
- * Author: Urs Zurbuchen
- *
- * Compile:
- * cl df.c (for Microsoft C)
- *
- * Revision history
- * When Who What
- * 30. 4.1989 zu Support for options -d and -f
- * Prepared for submission to Usenet.
- *
- * Last released:
- * 30. 4.1989 Ver. 1.1 Usenet, comp.binaries.ibm.pc
- *
- *---------------------------------------------------------------------------
- */
-
- #include <stdio.h>
- #include <dos.h>
- #include <string.h>
- #include <process.h>
- #include <stdlib.h>
- #include <setjmp.h>
-
-
- long zehner[3] = { 1000000, 1000, 1 };
- jmp_buf jb;
- char error_handler[4] = { 0xb8, 0, 0, 0xcf };
-
- #ifdef LINT_ARGS
- char *basename( char * );
- int main( int, char ** );
- void print_number( long );
- void print_statistics( unsigned char );
- void setvector( unsigned int );
- void Usage( char * );
- #endif
-
-
- int main( argc, argv )
- int argc;
- char **argv;
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
- int drives, floppies;
- int NoFloppies = 1, NoDisks = 0;
- unsigned int olderr_offset, olderr_segment;
- unsigned char i;
- void print_statistics(), setvector();
-
- /* initialize for error handling */
- inregs.x.ax = 0x3524; /* get error handler vector */
- intdosx( &inregs, &outregs, &segregs );
- olderr_offset = outregs.x.bx;
- olderr_segment= segregs.es;
- setvector( (unsigned int)error_handler );
-
- /* parse command line arguments */
- if( argc > 1 ) {
- for( i = (unsigned char) 1; (int)i < argc; i++ ) {
- if( argv[i][0] == '-' ) {
- switch( argv[i][1] ) {
- case '?':
- case 'h':
- Usage( argv[0] );
- exit( -1 );
- break;
- case 'f':
- NoFloppies = 0;
- break;
- case 'd':
- NoDisks = 1;
- break;
- default:
- fprintf( stderr, "Unknown option %c\n",
- argv[i][1] );
- Usage( argv[0] );
- break;
- }
- } else if( strlen( argv[i] ) == 2 && argv[i][1] == ':' ) {
- print_statistics( (unsigned char)tolower( (int)argv[i][0] ) -
- (int)'a' );
- exit( 0 );
- } else {
- fprintf( stderr, "df: invalid argument %s\n",
- argv[i] );
- Usage( argv[0] );
- exit( 1 );
- }
- }
- }
-
- /* determine number of logical drives in system */
- inregs.h.ah = 0x19; /* get current disk */
- intdos( &inregs, &outregs );
- inregs.h.dl = outregs.h.al;
- inregs.h.ah = 0x0e; /* select disk */
- intdos( &inregs, &outregs );
- drives = outregs.h.al;
- /* we now have the number of logical drives. But, this number *
- * might be wrong. It is just the value of the 'lastdrive=' *
- * command in config.sys which defaults to five if not specified*
- * We will have to test for the drives presence anyway. */
-
- /* determine number of physical floppy drives in system */
- int86( 0x11, &inregs, &outregs ); /* equipment determination */
- floppies = ( outregs.h.al & 0x01 ) ? ( outregs.h.al >> 6 ) +1 : 0;
-
- /* now print statistics */
- /* - for floppies */
- if( NoFloppies == 0 )
- for( i = (unsigned char) 0; (int)i < floppies; i++ )
- print_statistics( i );
-
- /* - for harddisks */
- if( NoDisks == 0 )
- for( i = (unsigned char) 2; (int)i < drives; i++)
- print_statistics( i );
-
- /* restore vector for error handling */
- inregs.x.ax = 0x2524; /* get error handler vector */
- outregs.x.dx = olderr_offset;
- segregs.ds = olderr_segment;
- intdosx( &inregs, &outregs, &segregs );
-
- return( 0 );
- }
-
- void print_statistics( drive )
- unsigned char drive;
- {
- union REGS iregs, oregs;
- long total, free;
- static int firsttime = 0;
- void print_number();
- int checkdrive();
-
- if( firsttime++ == 0 )
- printf( "Total space Free space Drive\n" );
-
- /* Try to print the statistics. If we try to read an inexistent *
- * drive the operating system calls its 'fatal error' handler *
- * (via INT 24h). Because we redirected this vector we will get *
- * control again in case of an error. In such a case the program*
- * just continues with the next drive. */
- if( setjmp( jb ) != 0 )
- return;
-
- iregs.h.ah = 0x36; /* get disk space */
- iregs.h.dl = drive +1;
- intdos( &iregs, &oregs );
- if( oregs.x.ax != 0xffff ) {
- total = (long)oregs.x.ax * (long)oregs.x.cx * (long)oregs.x.dx;
- free = (long)oregs.x.ax * (long)oregs.x.cx * (long)oregs.x.bx;
- print_number( total );
- print_number( free );
- printf( "%3.1ld%% ", free / (total / 100L) );
- printf( " %c:\n", drive + 'a' );
- }
- }
-
- void print_number( n )
- long n;
- {
- int i = 0, has_printed = 0;
- long c;
-
- /* if the number is greater than 999'999'999 we output it as it is */
- if( n > 999999999 )
- printf( "%ld", n );
- else
- while( i < 3 ) {
- if( has_printed )
- printf( "'" );
- if( (c = n / zehner[i] ) >= 1L ) {
- printf( (has_printed ? "%.3ld" : "%3.1ld"), c );
- has_printed = 1;
- } else
- printf( has_printed ? "000" : " " );
- n %= zehner[i++];
- }
- printf( " " );
- }
-
-
- void setvector( func )
- unsigned int func;
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
-
- segread( &segregs ); /* pick up segment registers */
- inregs.x.ax = 0x2524; /* set our error handler vector */
- inregs.x.dx = func;
- intdosx( &inregs, &outregs, &segregs );
- }
-
-
- void Usage( prog )
- char *prog;
- {
- fprintf( stderr, "Usage is:\n" );
- fprintf( stderr, "%s: [-? | -h] [-f | -d] [d:]\n", strlwr( basename( prog )) );
- fprintf( stderr, " -?, -h display this message\n" );
- fprintf( stderr, " -f check floppies, too\n" );
- fprintf( stderr, " -d do not check harddisks\n" );
- fprintf( stderr, " d: check only drive d:\n" );
- return;
- }
-
- char *basename( name )
- char *name;
- {
- char *pos;
-
- if( (pos = strrchr( name, '/' )) == NULL &&
- (pos = strrchr( name, '\\' )) == NULL )
- pos = name;
- else
- pos++;
-
- return( pos );
- }
-
-
-
-