home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 6 File
/
06-File.zip
/
du.zip
/
du.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-29
|
4KB
|
149 lines
/* Unix-style du for OS/2 */
/*
* syntax: du [-s] [directory-list]
* -s gives only summary of sizes for directories named on commandline.
* If no directories are specified, the current directory is assumed.
* Size of subtree given, then contribution by current node in parenthesis:
*
* 1234 ( 567) foo
*
* This entry shows that the subtree below and including directory foo uses
* 1234 bytes, and foo itself contains files accounting for 567 bytes. The
* remainder is in files in subdirectories below foo.
*
* Pipe the result through the sort filter to see the space hogs grouped at
* the end of the list.
*/
/*
* Copyright 1993 by Kenneth Porter (shiva@well.sf.ca.us).
* Freely redistributable.
* Code may be used if attribution given.
*/
#define INCL_NOPM
#define INCL_NOCOMMON
#define INCL_DOSERRORS
#define INCL_DOSFILEMGR
#include <os2.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void du(char *dirname, int summary);
static long du2(char *dirname, int silent, long *pfiles);
static void ShowDirSize(char *dirname, long size, long files);
static void FileFindError(char *dirname, ULONG error, char *what);
int main(int argc, char *argv[])
{
int i,summary;
--argc;
++argv;
// check for summary switch
if (argc && 0 == strcmp(argv[0],"-s")) {
summary = 1;
--argc;
++argv;
}
else summary = 0;
// check if any directories were specified on the command line
if (!argc) du(".",summary);
else for (i=0; i<argc; i++) du(argv[i],summary);
return 0;
}
void du(char *dirname, int summary)
{
long size,files;
size = du2(dirname,summary,&files);
if (summary && 0 != size) ShowDirSize(dirname,size,files);
}
long du2(char *dirname, int silent, long *pfiles)
{
// first search for directories, doing them recursively, then do files
ULONG rc;
long size=0, subfiles;
HDIR hdir;
ULONG SearchCount;
FILEFINDBUF3 *pbuf;
char namebuffer[CCHMAXPATH], subbuffer[CCHMAXPATH];
pbuf = calloc(1,sizeof *pbuf);
*pfiles = 0;
strcpy(namebuffer,dirname);
if ('\\' != namebuffer[strlen(namebuffer)-1]) strcat(namebuffer,"\\");
strcat(namebuffer,"*");
SearchCount = 1;
hdir = HDIR_CREATE;
rc = DosFindFirst((PSZ)namebuffer,&hdir,
MUST_HAVE_DIRECTORY|
FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM|FILE_ARCHIVED,
pbuf,sizeof *pbuf,&SearchCount,FIL_STANDARD);
while (ERROR_NO_MORE_FILES != rc) {
if (0 != rc) {
DosFindClose(hdir);
FileFindError(dirname,rc,"directory");
return 0;
}
/* !!!!!!!!!!!!!!!! This is the spot that gives me grief! */
/* Occasionally a normal file is returned, so the following test is
necessary */
if (pbuf->attrFile & FILE_DIRECTORY) {
if (0 != strcmp(pbuf->achName,".") &&
0 != strcmp(pbuf->achName,"..")) {
strcpy(subbuffer,dirname);
if ('\\' != subbuffer[strlen(subbuffer)-1])
strcat(subbuffer,"\\");
strcat(subbuffer,pbuf->achName);
size += du2(subbuffer,silent,&subfiles);
}
}
#if 0
else printf("File %s\\%s returned as directory\n",
dirname,pbuf->achName);
#endif
SearchCount = 1;
rc = DosFindNext(hdir,pbuf,sizeof *pbuf,&SearchCount);
}
DosFindClose(hdir);
hdir = HDIR_CREATE;
SearchCount = 1;
// search for anything that's not a directory
rc = DosFindFirst((PSZ)namebuffer,&hdir,
FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM|FILE_ARCHIVED,
pbuf,sizeof *pbuf,&SearchCount,FIL_STANDARD);
while (ERROR_NO_MORE_FILES != rc) {
if (0 != rc) {
DosFindClose(hdir);
FileFindError(dirname,rc,"file");
return 0;
}
*pfiles += pbuf->cbFileAlloc;
SearchCount = 1;
rc = DosFindNext(hdir,pbuf,sizeof *pbuf,&SearchCount);
}
DosFindClose(hdir);
size += *pfiles;
if (!silent) ShowDirSize(dirname,size,*pfiles);
free(pbuf);
return size;
}
void ShowDirSize(char *dirname, long size, long files)
{
printf("%10ld (%10ld) %s\n",size,files,dirname);
}
static void FileFindError(char *dirname, ULONG error, char *what)
{
fprintf(stderr,
"Search failed for %s '%s'; reason %d\n",
what,dirname,error);
}