[comp.sources.atari.st] v00i051: mwc:all: DU - un*x like disk usage reporting program

atari-sources-request@daisy.UUCP (12/25/87)

Submitted by: atari!imagen!ucbvax!ssyx!koreth (Steven Grimm)
comp.sources.atari.st: Volume 0, Issue 51
Archive-name: du.c



-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-
[Editor's Note]
	this was a simple, elegant program until i got my hacking little
hands on it. Anyway it now supports the -s flag and directory names as
arguements. If you don't have the man entry for du, this program reports
disk usage for a directory and it's subdirectories (if any). The -s flag
suppresses reporting subdirectories. The checksum is:

bytes =     3428(     3584)   cksm =  666   du.c

-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-

Here's a submission to comp.sources.atari.st.  Use it in good health.

#include <stdio.h>
#include <osbind.h>

/*
** DU.C
**
** Shows disk usage in a directory tree.
**
** Written by Steven Grimm, 11-19-87
**
** Usage:
**  du.ttp
*/

typedef struct {
        char    junk[21];
        char    attrib;
        int     time;
        int     date;
        long    length;
        char    name[14];
} DTA;

extern int getopt(), optind;
extern char *optarg;
int aflag, sflag;


/* Somewhat specialized long-to-ascii converter. */
char *ltoa(num,string)
register long num;
register char *string;
{
        register int ptr=0, flag=0;
        register long div=1000000000L;
        if (num<0)
        {
                string[ptr++]='-';
                num=0-num;
        }
        while ((div /= 10) >0)
        {
                if ((!(num/div))&&(!flag))
                        ++ptr;
                else
                {
                        string[ptr++]=num/div+48;
                        num %= div;
                        ++flag;
                }
        }
        if (! flag)
                string[ptr++]='0';
        string[ptr++]=' ';
        string[ptr]=0;
        return string;
}

/*
** Find disk usage in a directory.  Returns number of 1K blocks in the
** directory and its descendants.
**
** Input:
**      dir     Directory to search, ending in "\"
*/
long du(dir)
char *dir;
{
        DTA     dta;
        long    total;          /* Running total of disk usage */
        int     fstat;          /* Status returned from Fs{first,next}() */
        char    filespec[256];  /* Path and wildcard to search on */

        Fsetdta(&dta);
        strcpy(filespec, dir);
        strcat(filespec, "*.*");
        total = 0L;
        
        fstat = Fsfirst(filespec, 0x3f);
        
        while (fstat == 0)
        {
                if (dta.attrib & 0x10)  /* Search subdirectories */
                {
                        if (strcmp(dta.name, ".") && strcmp(dta.name, ".."))
                        {
                                strcpy(filespec, dir);
                                strcat(filespec, dta.name);
                                strcat(filespec, "\\");
                                total += du(filespec);
                                Fsetdta(&dta);
                        }
                }
                else
                        total += (dta.length+1023) / 1024;
                fstat = Fsnext();
        }
	if(!sflag) {
	        strcpy(filespec, "                 ");
	       	Cconws(ltoa(total, filespec));
	        Cconws(dir);
	       	Cconout(13);
	        Cconout(10);
	}
        return total;
}

main(argc,argv)
int argc;
char *argv[];

{
	char *disk, dum[255];
	int c;
	long total;
	
	if(argc == 0) {
		fprintf(stderr, "Usage is: du [-a] [-s] directory\n");
		exit(1);
	}

	sflag = 0; 
	aflag = 0; 

	while((c = getopt(argc, argv, "as")) != EOF)
		switch(c) {
			case 'a':
				aflag++;
				break;
			case 's':
				sflag++;
				break;
			default:
				fprintf(stderr, "Illegal option '%c'\n", c);
				break;
		}
	if(optind >= argc) {
		strcpy(disk, ".\\");
	        total = du(disk);
	}
	else {
		strcpy(disk,argv[optind]);
		if(disk[strlen(disk) - 1] != '\\')
			strcat(disk,"\\");
		total = du(disk);
	}
	if(sflag) {
	        strcpy(dum, "                 ");
	       	Cconws(ltoa(total, dum));
	        Cconws(disk);
	       	Cconout(13);
	        Cconout(10);
	}

	exit(0);
}