home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff345.lzh
/
Du
/
du.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-16
|
10KB
|
478 lines
/*
* du.c
* (C) 1986 Software Solution, all rights reserved
*----------------------------------------------------------------------------
*
* Original taken from Fish Disk #48
*
* - modified on May 89, emitted Mar 90 (since no original enhancements) by:-
*
* Gary Duncan
* 24 Inkster St
* Kambah ACT 2902
* Australia
* ~~~~~~~~~
*
*
* reasons as follows :-
*
* 1. print all files in dir at once ( original algorithm printed
* files and sub-dirs in given, unordered way ).
* - this is the major functional change.
*
* 2. allow ^C abort - every text-cruncher should have it.
*
* 3. print dirs in a redpen if not deselected ( looks much better )
*
* 4. changed code to be compiled under AZTEC 16-bit ints
* ( it would be helpful if people flagged their code with
* the compilation environment - hint ).
*
* Limitations ( the excession of will cause a GURU most likely )
*
* a. 50 levels of dir nesting ( unreasonable ???!!!! )
* b. file name path length < 200 ( " " )
*
*
*----------------------------------------------------------------------------
*
* du is patterned after the Unix(tm) du command. Its default action is to
* give the total number of disk blocks used by a directory and recursively,
* its subdirectories.
*
* options:
*
* -a ; prints blocks use by files and Directories
*
* -s ; sum of all blocks used by a directory and its subdirectories.
*
* -n ; no redpen for dir'd --GMD--
*
* Bug reports or suggestions should be sent to: <<< original >>>
* The Software Solution
* 16850 S.W. Timberland Dr.
* Aloha, Oregon 97007
*/
#include <stdio.h>
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "exec/memory.h"
#include "gd_functions.h"
extern char *indent() ;
extern long Recursive_Sum () ;
extern char *MakeDate[] ;
char *version = "V1.1" ; /* every PD program should have one */
/* Vers1.0 is the presumed version GMD modified */
char banner[100] ;
int t_flag = 0; /* summary only flag */
int a_flag = 0; /* list disk usage for both files and directories */
struct FileLock *flockstt = NULL ;
char *mostbug = "\n\n" ; /* extra \n for 'most' - see intro */
char *myname; /* name by which this command has been called i.e."du" */
char *redpen = " \x1b[33m"; /* red pen */
char *witepen = "\x1b[0m "; /* white pen */
#define NEST_LVL 50 /* arbitrary dir nesting level */
char *dirs[NEST_LVL] = NULL ;
int level = 0 ;
int Xblksz ;
main(argc, argv)
int argc;
char **argv;
{
int j , ch ;
char *cur_dir , *ptr ,*rtp ;
long total = 0 ;
ptr = MakeDate[0] ;
/*
* fiddle around to extract only the ddmmyy from date string
*/
while ( *ptr++ != ' ') ;
rtp=ptr;while(*rtp++!=' ');*--rtp='\0'; /* hackers practise, avoid */
sprintf ( banner ,
"DU : %s ; (original by Joe Mueller) , (v1.1 by Gary Duncan)\n" ,
ptr , version ) ;
printf ( "%s" , banner ) ; /* announce program */
myname = *argv++;
for ( j=0 ; j < 50 ; ++j ) /* clear array */
dirs[j] = NULL ;
while ( --argc )
{
if ( *(ptr = *argv ) == '-' )
{ /* handle options ( - ) */
++argv ;
ch = *++ptr ;
++ptr ;
switch ( ch )
{
case 'n': /* no redpen for dirs */
case 'N':
redpen = " <d>" ;
witepen = "" ;
break;
case 't':
case 'T':
if (a_flag)
usage();
t_flag++; /* sum only */
break;
case 's': /* block size filter */
case 'S':
if ( *ptr ) /* check for block size filter */
{
if ( sscanf (ptr , "%d" , &Xblksz ) != 1 )
usage () ;
}
else
usage() ;
break;
case 'a':
case 'A':
if (t_flag)
usage();
a_flag++; /* all files reported */
break;
default:
usage();
}
}
}
if (*argv)
{
while (cur_dir = *argv++)
{
total = Recursive_Sum(cur_dir) ;
printf("%5ld %s%s%s%s",
total, redpen, dirs[0] ,witepen , mostbug );
}
}
else
{
total = Recursive_Sum(argv);
printf("%5ld %s%s%s%s",
total , redpen , dirs[0] , witepen , mostbug );
}
exit (0);
}
/***************************************************************************
Name : Recursive_Sum
Purpose:
Entry :
Returns :
****************************************************************************/
long Recursive_Sum (fn)
char *fn; /* directory file name */
{
long total = 0 ;
int val;
long temp ;
struct FileLock *flock, *flockold ;
struct FileInfoBlock *fib ;
struct FileInfoBlock *fiblast;
char *gfib ;
int foxy = 0 ;
level++ ; /* dir indentation level */
fib = AllocMem((long)sizeof(*fib), MEMF_CLEAR);
if (fib == NULL)
{
fprintf(stderr,"%s: unable to allocate space for fileinfo block\n",
myname);
return 0;
}
if ( (flock = Lock(fn, ACCESS_READ)) == NULL )
{
fprintf(stderr,"%s: unable to lock %s\n", myname, fn);
FreeMem(fib, (long)sizeof(*fib));
return 0;
}
flockold = NULL;
if (Examine(flock,fib)) /* process all under this dir */
{
if (fib->fib_DirEntryType > 0)
{ /* it's a directory */
flockold = CurrentDir(flock);
if ( flockstt == NULL )
flockstt = flockold ; /* hold initial dir ptr for a ^C */
gfib = fib->fib_FileName ; /* last is current */
temp = strlen(gfib) + 1 ; /* 1 for \0 */
dirs[level-1] = AllocMem( temp , MEMF_CLEAR); /* mem for dir string */
if (dirs[level-1] == NULL)
{
fprintf(stderr,"%s: unable to allocate space for dir ptr\n",
myname);
return 0;
}
strcpy ( dirs[level-1] , gfib ) ; /* copy dir name */
}
total += fib->fib_NumBlocks;
/* --- now scan for files --------------------*/
val = 0 ;
Examine(flock,fib) ; /* now look for dirs */
while (ExNext(flock, fib))
{
if ( breakcheck() )
break ;
if ( fib->fib_DirEntryType < 0 ) /* file ? */
{
++foxy ;
val = fib->fib_NumBlocks; /* yes */
++val ; /* add 1 for info block -
?? correct */
if (a_flag && (val > Xblksz) )
printf("%5d %s%s\n",
val , indent(level), fib->fib_FileName );
total += val ;
}
else
foxy = -1 ;
}
if ( (foxy < 0) && (a_flag) )
{
foxy = 147 ; /* mysterious magic # */
printf ( "\n" ) ;
}
Examine(flock,fib) ; /* now look for dirs */
while (ExNext(flock, fib))
{
if ( breakcheck() )
break ;
if ( fib->fib_DirEntryType > 0) /* dir ? */
{ /* found a subdirectory */
val = Recursive_Sum(fib->fib_FileName); /* recursive call */
++val ; /* add 1 for info block -
?? correct */
if ( (t_flag==0) && (val > Xblksz) )
printf("%5d %s%s%s%s\n", val,redpen,indent(level),
fib->fib_FileName, witepen );
total += val ;
}
}
}
FreeMem(fib, (long)sizeof(*fib));
if (flockold != NULL)
CurrentDir(flockold); /* change directories back */
UnLock(flock);
FreeMem ( dirs[level] , (long)strlen(dirs[level]) ) ;
dirs[level--] = NULL ;
if ( breakcheck() ) /* ^C abort check */
{
fprintf ( stderr , "\n^C\n" ) ;
hexit () ;
}
return total;
}
/***************************************************************************
Name : indent
Purpose: generates a dir string , given level req'd.
- uses external list of ptrs to dir names.
Entry :
Returns :
****************************************************************************/
char *indent ( no )
int no ;
{
static char citats[200] ; /* indentation space buffer - nom. size */
int j ;
citats[0] = 0 ;
for ( j=0 ; j < no ; ++j )
{
strcat (citats , dirs[j]);
strcat (citats , "/" ) ;
}
return ( citats ) ;
}
/***************************************************************************
Name : breakcheck
Purpose:
Entry :
Returns :
****************************************************************************/
breakcheck()
{
return ((SetSignal(0L,0L) & SIGBREAKF_CTRL_C) );
}
/***************************************************************************
Name : hexit
Purpose:
Entry :
Returns :
****************************************************************************/
int hexit ()
{
int j ;
fflush ( stdout ) ;
if (flockstt != NULL)
CurrentDir(flockstt); /* change to orig dir */
while ( level )
{
FreeMem ( dirs[level] , (long)strlen(dirs[level]) ) ;
--level ;
}
exit (0) ;
}
Chk_Abort()
{
return(0);
}
/***************************************************************************
Name : usage
Purpose:
Entry :
Returns :
****************************************************************************/
int usage ()
{
static char *rats[] = {
"Usage: du [-a] [-t] [-n] [-sNNN] [vol: / dir list]...\n" ,
" a = print # of blocks used in all files and dirs \n" ,
" n = deselect pretty red-pen DIR hiliting\n",
" s = don't print those with lesser than NNN blocks\n",
" t = grand total of blocks only \n" ,
"\n",
" no a,t options = directories only\n",
""
} ;
int j = 0 ;
char *ptr ;
while ( *(ptr = rats[j++]) )
fprintf ( stderr, ptr ) ;
hexit () ;
}