/********************************************************************\ * * * Dave's DU version 1.01 * * * * ©1991 by Dave Schreiber. All rights reserved. This program may * * be freely distributed. The only charges allowed in relation to * * distributing this program is in relation to media, shipping, and * * handling costs. * * * * Version list: * * 1.02 (05/24/91) - Improved CTRL-C handling * * 1.00 (04/29/91) - Original release version * * * * Compiled with SAS/C V5.10. To compile, do the following: * * 1> lc DU * * 1> blink with DU.lnk * * * \********************************************************************/ #include #include #include #include #include #include #include ULONG *DOSBase; /*Function prototypes*/ ULONG __regargs getDirSize(BPTR lock,char *dirName); void interpretArgs(int argc,char *argv[],WORD *countDirs,WORD *countFiles, char *dirName); void printSize(char *dirName,ULONG size); void printHelp(void); void ctrlC_Handler(void); /*-------------------*/ /*Pragmas*/ #pragma syscall AllocMem C6 1002 #pragma syscall FreeMem D2 0902 #pragma syscall FindTask 126 901 #pragma libcall DOSBase CurrentDir 7E 101 #pragma libcall DOSBase Examine 66 2102 #pragma libcall DOSBase ExNext 6C 2102 #pragma libcall DOSBase Lock 54 2102 #pragma libcall DOSBase UnLock 5A 101 /*-------*/ /*Global variables*/ WORD countFiles,countDirs; struct Task *task; BYTE quitNow=FALSE; /*----------------*/ /*Defines*/ #define ERROR 0xFFFFFFFF #define ABS(x) ((x) < 0 ? -(x) : (x)) /*-------*/ /*Main. Initializes, find the directory size, and then cleans up*/ main(int argc,char *argv[]) { BPTR lock; char dirName[256]; LONG totalSize; /*Interpret the command line arguments*/ interpretArgs(argc,argv,&countDirs,&countFiles,dirName); /*Replace the CTRL-C handler*/ signal(SIGINT,ctrlC_Handler); /*Get a lock on the provided directory name*/ lock=Lock(dirName,SHARED_LOCK); if(lock == NULL) /*Abort if the directory isn't there*/ { fputs("Couldn't access the directory you requested; aborting.\n", stderr); exit(200); } /*Get the size of the contents of the directory*/ totalSize=getDirSize(lock,dirName); /*Abort if something went wrong, otherwise print the directory size*/ if(totalSize == ERROR) fputs("Error. Aborting!\n",stderr); else if(!countDirs && !quitNow) printSize(dirName,totalSize); UnLock(lock); /*Free the lock on the top directory*/ exit(0); /*And exit*/ } /*Get the size of the contents of the specified directory (recursive)*/ ULONG __regargs getDirSize(BPTR lock,char *dirName) { register ULONG totalSize=0; register struct FileInfoBlock *fib; register BPTR dirLock,oldCurDir; register UWORD dirNameLen; register ULONG size; dirNameLen=strlen(dirName); /*Allocate (longword aligned) FileInfoBlock structure*/ fib=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC,MEMF_CLEAR); if(fib==NULL) return(ERROR); /*Save the current directory, and change to the directory we need*/ /*to find the size of.*/ oldCurDir=CurrentDir(lock); Examine(lock,fib); /*For each file/directory, get the size...*/ while(ExNext(lock,fib) && !quitNow) { totalSize++; /*Add 1 (for the directory entry)*/ if(ABS(fib->fib_EntryType) != 4) /*If the file isn't a link...*/ { if(fib->fib_EntryType < 0) /*If the file isn't a directory*/ { /*get the size directly*/ /*Add the size to the total*/ totalSize+=fib->fib_NumBlocks; if(countFiles) /*If the user wants the size of each file*/ { /*printed, print the file size*/ if(dirNameLen!=0 && dirName[dirNameLen-1]!=':') strcat(dirName,"/"); strcat(dirName,fib->fib_FileName); printSize(dirName,totalSize); dirName[dirNameLen]=NULL; } } else /*It's a directory*/ { /*Get the lock on the directory*/ dirLock = Lock(fib->fib_FileName,SHARED_LOCK); if(dirLock == NULL) /*Abort if there was a problem getting*/ { /*a lock on the directory*/ CurrentDir(oldCurDir); fputs("Couldn't lock directory:",stderr); fputs(fib->fib_FileName,stderr); fputs("\n",stderr); FreeMem(fib,sizeof(struct FileInfoBlock)); return(ERROR); } /*Create the full name of the directory we're going to */ /*descend into*/ if(dirNameLen!=0 && dirName[dirNameLen-1]!=':') strcat(dirName,"/"); strcat(dirName,fib->fib_FileName); /*Recursively get the directory size*/ size=getDirSize(dirLock,dirName)-1; UnLock(dirLock); if(size==ERROR) /*Abort if there was an error*/ { CurrentDir(oldCurDir); FreeMem(fib,sizeof(struct FileInfoBlock)); return(ERROR); } else totalSize+=size+2; /*Otherwise, add the size to the total*/ /*Restore the old directory name*/ dirName[dirNameLen]=NULL; } } } CurrentDir(oldCurDir); if(quitNow) /*If the user pressed CTRL-C, abort*/ fputs("*** Break: du\n",stderr); else if(countDirs) /*If CTRL-C wasn't pressed, print the size of the*/ printSize(dirName,totalSize); /*directory (if the user wants it)*/ /*Deallocate the FileInfoBlock*/ FreeMem(fib,sizeof(struct FileInfoBlock)); /*Return the total size*/ return(totalSize); } /*Interpret the command line arguments*/ void interpretArgs(int argc,char *argv[],WORD *countDirs,WORD *countFiles, char *dirName) { int i; if(argv[1][0]=='?') /*The user is asking for help*/ { printHelp(); exit(0); } /*Set these variables to their default value*/ *countDirs=TRUE; *countFiles=FALSE; strcpy(dirName,""); for(i=1;i]"); puts("-s -- Print only the grand total size"); puts("-a -- Print the size for each file"); puts(" -- Starting directory"); puts(""); return; } /*CTRL-C handler*/ void ctrlC_Handler(void) { signal(SIGINT,ctrlC_Handler); quitNow=TRUE; return; }