home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum4.lzh
/
SPRACHEN
/
C
/
DU
/
du.c
Wrap
C/C++ Source or Header
|
1987-12-14
|
8KB
|
249 lines
/* DU.C (Disk usage)
*
* Displays directory sizes similar to the UNIX DU function.
*
* This program is based on Size.C by Avy Moise, 1987, Toronto, Canada
*
* Modified by Tom Leitner, Sep. 1987, Graz, Austria
*
* Usage is : DU [<opts>] <directory> [<opts>]
*
* It will collect all the sizes (not including file descriptor and
* directory space taken) for the specified directory and prints
* them in a table along with all subdirectories. The directory
* size is printed in Bytes, kBytes and 256 Byte Sector Units.
* If the directory specification is omitted, the current directory
* will be used.
*
* Note: The # of files displayed include also the directory files.
*
*/
/* system includes */
#include <stdio.h>
#include <dir.h>
#include <modes.h>
#include <sgstat.h>
#include <time.h>
/* constants & macros */
#define RBF (1) /* random block file found opened */
#define PIPE (2) /* pipe file opened */
#define NET (4) /* network file opened */
#define TRUE 1 /* logical true */
#define FALSE 0 /* logical false */
#define KB(x) (x+1023L)/1024 /* formula to calculate kB from bytes */
#define SECT(x) (x+255L)/256 /* formula to calc. sectors from bytes */
#define MAXPATH 256 /* max. # of characters for path name */
/* global variables */
char path[MAXPATH] = ""; /* string to store the path */
int files = 0; /* # of files found */
int dirs = 0;/* # of directories found
*/
char flag_total = FALSE; /* just print a summary */
char dir_flag;/* indicates a directory read
*/
struct sgtbuf cur_time; /* current time */
char *root; /* root directory to start from */
/*--------------------------------- M A I N ----------------------------------*/
main(argc, argv)
int argc;
char *argv[];
{
unsigned long filesize(), tot_size;
get_parms(argc, argv);
if (!flag_total) {
getime(&cur_time);
printf("Disk usage starting from \"%s\" on ", root);
print_date(&cur_time);
printf("\n\nDirectory name Bytes kBytes Sectors File #\n");
printf("-------------- -------- ------- ------- -------\n");
}
tot_size = filesize(root);
printf("\nTotal of %lu kBytes (%lu sectors) in %d directories and %d files.\n\n",
KB(tot_size), SECT(tot_size), dirs, files);
}
/*------------------- print the date supplied in the buffer ------------------*/
print_date(bp)
struct sgtbuf *bp;
{
register int i;
char sbuf[11];
sprintf(sbuf, "19%2d-%2d-%2d", bp->t_year, bp->t_month, bp->t_day);
for (i = 0; i < 10; i++)
if (sbuf[i] == ' ') sbuf[i] = '0';
printf("%s ", sbuf);
sprintf(sbuf, "%2d:%2d:%2d", bp->t_hour, bp->t_minute, bp->t_second);
for (i = 0; i < 8; i++)
if (sbuf[i] == ' ') sbuf[i] = '0';
printf("%s", sbuf);
}
/*-------------------- parses command line for parameters --------------------*/
get_parms(argc,argv)
int argc;
char *argv[];
{
char *s;
int pc = 0;
while (--argc>0) {
if ((*++argv)[0] == '-') {
for (s = argv[0]+1;*s != '\0';s++)
switch(toupper(*s)) {
case 'A':
flag_total = TRUE;
break;
case '?':
usage();
exit(0);
default:
fprintf(stderr,
"%s: unknown option '%c'\n",
_prgname(),*s);
exit(1);
}
}
else if (pc == 0) {
root = argv[0];
pc++;
} else {
fprintf(stderr,"%s: only one parameter allowed\n",
_prgname());
exit(1);
}
}
if (pc == 0) root = ".";
}
/*------------------------- print usage explanations -------------------------*/
#define E(txt) fprintf(stderr, txt)
usage()
{
fprintf(stderr,"Syntax: %s <directory>\n",_prgname());
E("Function: displays information about disk usage\n");
E("Options : -a displays just the final summary\n");
}
#undef E(txt)
/*------------------------------ main algorithm ------------------------------*/
unsigned long filesize( filename )
char *filename;
{
unsigned long size=0L;
int fd, pl, dfiles;
DIR *dirp;
struct direct *dirrec;
static struct sgbuf stat;
/* set the dir_flag to FALSE by default */
dir_flag = FALSE;
/* setup the cumulative path name */
pl = strlen(path);
if (pl) strncat(path, "/", MAXPATH);
strncat(path, filename, MAXPATH);
/* try to open the file */
if( ((fd=open(filename,S_IREAD)) < 0) && /* regular file ? */
((fd=open(filename,S_IFDIR|S_IREAD)) < 0) ) /* directory ? */
fprintf(stderr,"Cannot open '%s'\n", filename);
/* successfully opened. check if it's on the right device */
else {
_gs_opt(fd, &stat);
if( (stat.sg_class == RBF) || (stat.sg_class == NET) ||
(stat.sg_class == PIPE) ) {
/* ok. we're on a valid device : now check if we hit a directory file */
if( stat.sg_att & S_IFDIR ) {
/* yes. we hit a directory file. close the FD and CHD into it. */
close(fd);
if( (dirp = opendir( filename )) && !chdir( filename) ) {
/* skip the "." and the ".." entries */
readdir(dirp); readdir( dirp );
/* get file sizes of all files in this directory */
dfiles = 0;
while (dirrec = readdir (dirp))
if (dirrec->d_addr) {
size += filesize(dirrec->d_name);
if (!dir_flag) {
dfiles++; /* update local file counter */
files++; /* update global file counter */
}
}
/* end of directory : close it and print the results */
closedir( dirp );
chdir("..");
if (!flag_total) printline(path, size, dfiles);
dirs++; /* update the directory counter */
dir_flag = TRUE;
}
/* ERROR occurred : can't CHD into this directory. */
else
fprintf(stderr, "Cannot chdir '%s'\n", filename);
/* the given filename was no directory. it's a normal file so just get its
size and increment the file count */
} else {
size = _gs_size( fd );
close( fd );
}
}
/* the given file name is not on a valid device */
else
fprintf(stderr,"Cannot read size - not a block special device\n");
}
/* reset the cumulative PATH string */
path[pl] = (char) NULL;
return( size );
}
/*-------------------------- print one table entry ---------------------------*/
printline(path, size, dfiles)
char *path;
unsigned long size;
int dfiles;
{
if (strlen(path) > 32) {
printf("%s\n", path);
path = "";
}
printf("%-32s %8lu %7lu %7lu %7d\n",
path, size, KB(size), SECT(size), dfiles);
}
/* E O F */