home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
sources
/
du.zoo
/
du.c
< prev
next >
Wrap
Text File
|
1992-04-13
|
11KB
|
413 lines
/*
** source file : #(@)du.c
** program desc : DU for OS/2 2.0
** author : John J. Allen
** last edited by : John J. Allen
** date created : Fri 10 April 1992
** version : 1.00.00
** verdate : Mon 13th Apr 1992
** comment : A du for OS/2 2.0
**
** (c) Copyright John J. Allen. 1990-1992.
**
** This program may be freely distributed and modified as long as the
** original copyright message remains intact.
**
** This program uses the regular expression parser distributed with the
** GNU Text Utilities.
**
** This is a 32bit OS/2 2.0 program and requires the IBM C Set/2 compiler.
** It has been compiled & tested under the LA release and I hope to
** be able to test it under GA RSN.
**
** All comments/suggestions for mod's etc... should be mailed to jja@wsl.ie
**
** example usage.
** du \*.c
** du \
** du \*map*
**
*/
#define INCL_FILEMGR
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <os2.h>
#include "regex.h"
char* copr="DU/2-Directory Usage, Release 1.00\n"
"(c) Copr. 1990-1992, John J. Allen\n";
unsigned long treeDepthToDisplay = 0xFFFFFFFF;
/* translate table for regexp functions */
static char upcase[0400] =
{ 000, 001, 002, 003, 004, 005, 006, 007,
010, 011, 012, 013, 014, 015, 016, 017,
020, 021, 022, 023, 024, 025, 026, 027,
030, 031, 032, 033, 034, 035, 036, 037,
040, 041, 042, 043, 044, 045, 046, 047,
050, 051, 052, 053, 054, 055, 056, 057,
060, 061, 062, 063, 064, 065, 066, 067,
070, 071, 072, 073, 074, 075, 076, 077,
0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
};
/*-----------------------------------oOo------------------------------------*/
void usage()
{
printf("%s\n", copr);
printf("usage: du [switches] {directory[\\filespec]}\n\n");
printf("switches are:\n");
printf("/? display this screen.\n");
printf("/Dn display tree to depth n.\n");
printf("/T display totals only. (same as /D1)\n");
}
/*-----------------------------------oOo------------------------------------*/
char* fileEx2RegEx(char* s)
{
static char buf[2048];
char* bp = buf;
char lastchar = '\0';
*bp++ = '^';
while (*s) {
switch (*s) {
case '*': {
strcpy(bp, "[^\\/:]*");
bp = strchr(bp, 0);
}
break;
case '?': {
*bp++ = '.';
}
break;
case '.':
case '$': {
*bp++ = '\\';
*bp++ = *s;
}
break;
case '+': {
if (lastchar == ']') {
if (isdigit(*(s+1))) {
int min=1, max=1;
s++;
max = atoi(s);
while (*s && isdigit(*s))
s++;
if (*s == ',') {
s++;
min = atoi(s);
while (*s && isdigit(*s))
s++;
}
s--;
sprintf(bp, "\\{%d,%d\\}", min, max);
bp = strchr(bp, 0);
}
}
else {
*bp++ = *s;
}
}
break;
default: {
*bp++ = *s;
}
}
lastchar = *s++;
}
*bp++ = '$';
*bp = '\0';
return buf;
}
/*-----------------------------------oOo------------------------------------*/
char* makePathSpec(char* dir, char* fileSpec)
{
static char pathSpec[255];
strcpy(pathSpec, dir);
if (*pathSpec && pathSpec[strlen(pathSpec)-1] != '\\')
strcat(pathSpec, "\\");
strcat(pathSpec, fileSpec);
return pathSpec;
}
/*-----------------------------------oOo------------------------------------*/
long duDir(char* directory, char* fileSpec)
{
HDIR hDir = HDIR_CREATE;
ULONG attribute = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
FILEFINDBUF3 resultBuf;
ULONG resultBufLen;
ULONG searchCount = 1;
ULONG fileInfoLevel = FIL_STANDARD;
ULONG returnCode;
char fullPathSpec[255];
long bytesOccupied = 0;
struct re_pattern_buffer buf;
char fastmap[(1 << CHAR_BIT)];
static unsigned long treeDepthCount = 0;
if ((strlen(directory) + strlen(fileSpec) + 2) >= sizeof(fullPathSpec)) {
printf("du: directory + filespec too long\n");
return 0;
}
strcpy(fullPathSpec, makePathSpec(directory, "*"));
returnCode = DosFindFirst
(
fullPathSpec,
&hDir,
attribute,
&resultBuf,
sizeof(resultBuf),
&searchCount,
fileInfoLevel
);
if (returnCode == 0) {
long fileCount = 0;
long dirCount = 0;
char* pattern = fileEx2RegEx(fileSpec);
treeDepthCount++;
buf.allocated = 10000;
buf.buffer = malloc(buf.allocated);
buf.fastmap = fastmap;
buf.translate = upcase;
re_compile_pattern (pattern, strlen(pattern), &buf);
re_compile_fastmap (&buf);
do {
if (resultBuf.attrFile & FILE_DIRECTORY) {
dirCount++;
if (strcmp(resultBuf.achName, ".") != 0 && strcmp(resultBuf.achName, "..") != 0) {
char newDirectory[255];
strcpy(newDirectory, makePathSpec(directory, resultBuf.achName));
bytesOccupied += duDir(newDirectory, fileSpec);
}
}
else {
if (re_match(&buf, resultBuf.achName, strlen(resultBuf.achName), 0, 0) != -1) {
fileCount++;
bytesOccupied += resultBuf.cbFile;
}
}
}
while (DosFindNext(hDir, &resultBuf, sizeof(resultBuf), &searchCount) == 0);
DosFindClose(hDir);
treeDepthCount--;
if (treeDepthCount < treeDepthToDisplay && fileCount > 0) {
printf("%10li %6li %6li %s\n", bytesOccupied, fileCount, dirCount, directory);
}
free(buf.buffer);
return bytesOccupied;
}
return -1;
}
/*-----------------------------------oOo------------------------------------*/
long du(char* directory)
{
static char dir[255];
long bytesOccupied = 0;
ULONG pathLen = sizeof(dir)-3;
ULONG driveNumber, logicalDriveMap;
DosQCurDisk(&driveNumber, &logicalDriveMap);
dir[0] = 'A' + (driveNumber-1);
dir[1] = ':';
dir[2] = '\\';
DosQCurDir(0, &dir[3], &pathLen);
switch (*directory) {
case '\\': {
strcpy(&dir[2], directory);
}
break;
case '\0': {
}
break;
default: {
/* is a drive specified */
if (strlen(directory) > 1 && directory[1] == ':') {
/* is it not a full path */
if (strlen(directory) > 2 && directory[2] != '\\') {
dir[0] = directory[0];
dir[1] = directory[1];
pathLen--;
DosQCurDir((toupper(dir[0]) - 'A')+1, &dir[2], &pathLen);
strcat(dir, "\\");
strcat(dir, directory);
}
else {
strcpy(dir, directory);
dir[0] = toupper(dir[0]);
}
}
else {
strcat(dir, "\\");
strcat(dir, directory);
}
}
}
if ((bytesOccupied = duDir(dir, "*")) == -1) {
char* fileSpec = strrchr(dir, '\\');
*fileSpec++ = '\0';
bytesOccupied = duDir(dir, fileSpec);
}
return bytesOccupied;
}
/*-----------------------------------oOo------------------------------------*/
int main(int argc, char* argv[])
{
int i, dirsCounted = 0;
long total = 0;
for (i=1; i < argc && *argv[i] == '/'; i++) {
char* c = argv[i]+1;
while (*c) {
switch (*c) {
case '?': {
usage();
return 0;
}
break;
case 't':
case 'T': {
treeDepthToDisplay = 1;
}
break;
case 'd':
case 'D': {
treeDepthToDisplay = atol(c+1);
/* skip to end of string */
while (*++c)
;
c--;
}
break;
default: {
usage();
printf("\nunknown switch character %c\n", *c);
return 3;
}
} /* endswitch */
c++;
} /* endwhile */
} /* endfor */
if (i == argc) {
long dirSize = du("");
if (dirSize != -1) {
total += dirSize;
dirsCounted++;
}
}
for (; i < argc; i++) {
long dirSize = du(argv[i]);
if (dirSize != -1) {
total += dirSize;
dirsCounted++;
}
} /* endfor */
if (dirsCounted > 1) {
printf("%10li\n", total);
}
return 0;
}
/*-----------------------------------oOo------------------------------------*/
/* (c) Copyright John J. Allen. 1990-1992. */
/*-----------------------------------oOo------------------------------------*/