/* Sizer.c by Fabbian G. Dufoe, III 350 Ling-A-Mor Terrace South St. Petersburg, Florida 33705 813-823-2350 GENIE: F.DUFOE3 This software is in the public domain. You may use it any way you wish. Sizer reports the number of bytes and blocks in a disk, file, or directory and all included subdirectories. The user selects the Sizer icon and uses extended selection to indicate the other files and directories he wants sized. Sizer will open a workbench window with the number of blocks and the number of bytes. To terminate the program the user clicks on the window's close gadget. Revison summary: 15 October 1991: Initial release. 18 May 1992: Fixed NULL pointer bug in GetSize() function. Function was passing a NULL pointer when it should have been passing a pointer to a NULL string. 13 June 1992: Added code for reporting blocks for old file system (OFS) and fast file system (FFS) disks. Made CountBlocks() and GetSize() static and moved their prototypes into this file. Added code to update display for directory sizes as well as files. */ #include #include #include "Sizer.h" /* Prototypes for functions defined in Sizer.c */ #ifndef __NOPROTO #ifndef __PROTO #define __PROTO(a) a #endif #else #ifndef __PROTO #define __PROTO(a) () #endif #endif static long CountBlocks __PROTO((int blocksize, LONG bytes)); static void GetSize __PROTO((BPTR lock, char *name, struct record *Record)); void main(int argc, char **argv) { struct WBStartup *argmsg; int i; struct FileInfoBlock IconBlock; /* Information about ".info" file */ BPTR ParentLock; struct record Record = { NORM, /* code */ 0, /* bytes */ 0, /* OFSblocks */ /* 13 June 1992 */ 0, /* FFSblocks */ /* 13 June 1992 */ 0, /* files */ 0 /* dirs */ }; struct WBArg *wb_arg; if (argc == 0) /* Started from Workbench */ { /* Since the program was started from the Workbench argv contains a pointer to the Workbench startup message. We'll save that pointer in argmsg. The Workbench startup message contains a pointer to an array of arguments. That pointer is in sm_ArgList. Each argument has a lock and a name. The first argument is the program itself. The number of arguments is stored in sm_NumArgs. */ argmsg = (struct WBStartup *)argv; wb_arg = argmsg->sm_ArgList; /* We'll try to open the input/output window. We'll continue only if we're successful. */ SizerIO(&Record); if (Record.code == NORM) { for (i = 1; i < argmsg->sm_NumArgs; i++) { /* We want to include the size of the icon file in our calculations. If the user selected a directory object we'll have to Examine() it to find out its name, then switch to its parent directory, append ".info" to the file name, and Examine() the icon file to get its size. */ if (*(wb_arg + i)->wa_Name == NULL) /* Directory object */ { if (Examine((wb_arg + i)->wa_Lock, &IconBlock) == 0) { Record.code = FAIL; SizerIO(&Record); break; } else { if (0 != (ParentLock = ParentDir((wb_arg + i)->wa_Lock))) { (void)strcat(IconBlock.fib_FileName, ".info"); GetSize(ParentLock, IconBlock.fib_FileName, &Record); UnLock(ParentLock); } } } else { strcpy(IconBlock.fib_FileName, (wb_arg + i)->wa_Name); (void)strcat(IconBlock.fib_FileName, ".info"); GetSize((wb_arg + i)->wa_Lock, IconBlock.fib_FileName, &Record); } GetSize((wb_arg + i)->wa_Lock, (wb_arg + i)->wa_Name, &Record); } if (Record.code == NORM) { Record.code = DONE; SizerIO(&Record); } Record.code = CLOSEIO; SizerIO(&Record); } } } static long /* 13 June 1992 */ CountBlocks(int blocksize, LONG bytes) /* FUNCTION This function calculates the number of disk blocks needed by a file based on the number of bytes in the file and the number of bytes in a block. The number of blocks is the sum of the File Header Block, the data blocks, and any File List Blocks. Data blocks are calculated by dividing the number of bytes by the block size and adding another data block for bytes left over (if there is a remainder). Every file has one File Header Block, which can accommodate up to 72 data blocks. If there are more data blocks, a File List Block is required for the file extension. The File List Block can accommodate 72 data blocks. There may be as many File List Blocks as needed for the data blocks. If there are no bytes in the file it is either an empty file or a directory. Either one requires a single block. INPUTS blocksize The number of bytes in a block bytes The number of bytes in the file RESULTS The function returns the number of blocks the file will require. The minimum value is 1. */ { long blocks; if (bytes > 0) { blocks = bytes / blocksize; if ((bytes % blocksize) != 0) { blocks++; } if ((blocks % 72) == 0) { blocks += blocks / 72; blocks--; } else { blocks += blocks / 72; } blocks += 1; } else { blocks = 1; } return(blocks); } static void /* 13 June 1992 */ GetSize(BPTR lock, char *name, struct record *Record) { struct FileInfoBlock infoBlock; BPTR objlock; BPTR olddir; if (Record->code == FAIL) return; olddir = CurrentDir(lock); if (*name == NULL) /* Directory object */ { /* Examine everything in the directory and accumulate the sizes. */ if (Examine(lock, &infoBlock) == 0) { Record->code = FAIL; SizerIO(Record); } else { Record->bytes += infoBlock.fib_Size; Record->OFSblocks += CountBlocks(488, 0); /* 13 June 1992 */ Record->FFSblocks += CountBlocks(512, 0); /* 13 June 1992 */ Record->dirs++; /* 13 June 1992 */ while ((ExNext(lock, &infoBlock) != 0) && (Record->code == NORM)) { if (infoBlock.fib_DirEntryType > 0) /* Directory */ { if ((objlock = Lock(infoBlock.fib_FileName, ACCESS_READ)) == 0) { Record->code = FAIL; SizerIO(Record); } else { GetSize(objlock, "\0", Record); /* 18 May 1992 */ UnLock(objlock); SizerIO(Record); /* 13 June 1992 */ } } else { Record->bytes += infoBlock.fib_Size; Record->OFSblocks += CountBlocks(488, infoBlock.fib_Size); /* 13 June 1992 */ Record->FFSblocks += CountBlocks(512, infoBlock.fib_Size); /* 13 June 1992 */ Record->files++; SizerIO(Record); } } } } else /* Plain file */ { if ((objlock = Lock(name, ACCESS_READ)) == 0) { Record->code = FAIL; SizerIO(Record); } else { if (Examine(objlock, &infoBlock) == 0) { Record->code = FAIL; SizerIO(Record); } else { Record->bytes += infoBlock.fib_Size; Record->OFSblocks += CountBlocks(488, infoBlock.fib_Size); /* 13 June 1992 */ Record->FFSblocks += CountBlocks(512, infoBlock.fib_Size); /* 13 June 1992 */ Record->files++; SizerIO(Record); } UnLock(objlock); } } (void)CurrentDir(olddir); return; }