/* bbscsumm.c         2/5/88 */
/* This code was derived from newest.c by Rick Richardson */

#include <ftw.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
/*
#include "bbscdef.h"
*/
 
extern char msg_text[1482];
extern char who_am_I[99];
extern char who_am_i[99];
extern char jnk[2];
extern char buf128[384];
extern char x_pathandfile[99];
extern char f_pathname[99];
extern char x_filename[20];
 
extern int toggle;

#define	DAYSIZE	15
#define	SIZSIZE	11
#define	SECS	(60L*60L*24L)
#define	EPOCH	9999999L
#define CRLF	"\n\r"

int	unreadable;
long	mtime;
long	atime;
long	Ctime;
long	bigsize;
int	files;
long	bytes;
int	bigflag;
int	timeflag;
char	*base();
static long	dayvec[] =
{
	0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 10L, 20L, 50L, 100L, 200L, 500L, EPOCH
};

static long	sizvec[] =
{
	0L, 1000L, 5000L, 10000L, 20000L, 50000L, 100000L, 200000L, 500000L,
	1000000L, EPOCH
};

int	afiles[DAYSIZE];
int	mfiles[DAYSIZE];
int	cfiles[DAYSIZE];
int	sizfiles[SIZSIZE];
long	now;

int
in(mindays, maxdays, when)
long	mindays, maxdays;
long	when;
{
	long	minsecs = mindays * SECS;
	long	maxsecs = maxdays * SECS;

	if ( (now-when)<maxsecs && (now-when)>=minsecs) return (1);
	return (0);
}

int
siz(minsiz, maxsiz, thissiz)
long	minsiz, maxsiz;
long	thissiz;
{
	if ( thissiz<maxsiz && thissiz>=minsiz) return (1);
	return (0);
}

int
fn(name, sp, what)
char	*name;
register struct stat	*sp;
{
	register int i;

	if (what != FTW_F && what != FTW_D)
	{
		++unreadable;
		return (0);
	}
	bytes += sp->st_size;
	if (what != FTW_F) return(0);
	++files;
	for (i = 1; i < DAYSIZE; ++i)
	{
		if (in(dayvec[i-1], dayvec[i], sp->st_mtime)) mfiles[i]++;
		if (in(dayvec[i-1], dayvec[i], sp->st_atime)) afiles[i]++;
		if (in(dayvec[i-1], dayvec[i], sp->st_ctime)) cfiles[i]++;
	}
	for (i = 1; i < SIZSIZE; ++i)
		if (siz(sizvec[i-1], sizvec[i], sp->st_size)) sizfiles[i]++;
	if (sp->st_mtime>mtime)
		{mtime = sp->st_mtime; (void)strcpy(who_am_I, name);}
	if (sp->st_ctime>Ctime)
		{Ctime = sp->st_ctime; (void)strcpy(x_pathandfile, name);}
	if (sp->st_atime>atime)
		{atime = sp->st_atime; (void)strcpy(who_am_i, name);}
	if (sp->st_size>bigsize)
		{bigsize = sp->st_size; (void)strcpy(buf128, name);}
	return (0);
}
summary()
{
	long	time();
	register int i, c, errflag = 0;
	portsout("\n\rCompiling statistics summary .........");
	now = time( (long *) 0);
	init();
	walk(f_pathname);
	stats(f_pathname);
	graf(afiles, mfiles, cfiles);
	return (0);
}

init()
{
	register int	i;

	unreadable = 0;
	mtime = 0;
	atime = 0;
	Ctime = 0;
	bigsize = 0;
	files = 0;
	bytes = 0;
	for (i = 1; i < DAYSIZE; ++i)
	{
		afiles[i] = 0;
		mfiles[i] = 0;
		cfiles[i] = 0;
	}
	for (i = 1; i < SIZSIZE; ++i)
		sizfiles[i] = 0;
}

walk(name)
register char	*name;
{
	while (ftw(name, fn, 10) > 0)
		;
}

stats(name)
char	*name;
{
	portsout("\n\r\n\rDirectory:  ");
	portsout(name);
	portsout("\n\rNewest access:  ");
	portsout(base(who_am_i));
	portsout(" at ");
	portsout(ctime(&atime));
	portsout("\n\rNewest modify:  ");
	portsout(base(who_am_I));
	portsout(" at ");
	portsout(ctime(&mtime));
	portsout("\n\rNewest change:  ");
	portsout(base(x_pathandfile));
	portsout(" at ");
	portsout(ctime(&Ctime));
	portsout("\n\rLargest file:   ");
	portsout(base(buf128));
	portsout(" is ");
	sprintf(x_filename, "%ld", bigsize);
	portsout(x_filename);
	portsout(CRLF);
	if (unreadable)
		portsout("\n\r\n\rUnreadable directories/files found\n\r\n\r");
}

char *base(nm)
char *nm;
{
	char *ptr;
	ptr = strrchr(nm, '/');
	ptr++;
	return(ptr);
}

graf(avec, mvec, cvec)
int	avec[];
int	mvec[];
int	cvec[];
{
	register int	i;
		for (i = 1; i < DAYSIZE; ++i)
		{
			if (dayvec[i] == EPOCH){
				(void) sprintf(msg_text,
		"%5ld - EPOCH days: %5d accessed %5d modified %5d changed\n\r",
					dayvec[i-1], avec[i], mvec[i], cvec[i]);
		portsout(msg_text); }
			else{
				(void) sprintf(msg_text,
		"%5ld - %5ld days: %5d accessed %5d modified %5d changed\n\r",
					dayvec[i-1], dayvec[i],
					avec[i], mvec[i], cvec[i] );
		portsout(msg_text); }
		}
		(void) sprintf(msg_text,
		"                    %5d TOTAL FILES, %7ld TOTAL BYTES\n\r\n\r",
			files, bytes);
		portsout(msg_text);

	if(toggle)
		{
		portsout("*** Depress a key to continue .......");
		portsin(jnk, 1);
		portsout("\n\r\n\r");
		}
		for (i = 1; i < SIZSIZE; ++i)
		{
			if (sizvec[i] == EPOCH){
				(void)sprintf(msg_text,"%7ld -  ULIMIT bytes: %5d files\n\r",
					sizvec[i-1], sizfiles[i] );
				portsout(msg_text); }
			else{
				(void)sprintf(msg_text,"%7ld - %7ld bytes: %5d files\n\r",
					sizvec[i-1], sizvec[i], sizfiles[i] );
				portsout(msg_text); }
		}
		(void)sprintf(msg_text,"                    %7ld TOTAL BYTES\n\r", bytes);
		portsout(msg_text);
	if(toggle)
		{
		portsout("\n\r*** Depress a key to continue .......");
		portsin(jnk, 1);
		portsout("\n\r\n\r");
		}
}
