#
/*
 *	Program to print usuage of various system
 *	tables
 *	switches are:
 *	-c	print coremap
 *	-s	print swapmap
 *	-p	print proc
 *	-t	print text
 *	-i	print inode
 *	-f	print file
 *	-l	print callout
 *	-h	print switches
 *	-m	print mount
 *	-C	print Clist
 */
#include "/usr/sys/data.h"
#include "/usr/sys/tty.h"
char regloc[1];

struct cblock
{	struct cblock	*c_next;
	char		characters[14];
} cfree[NCLIST], *cfreelist;
#define NDC11	1
#define NKL11	12
#define NOLPTS	2
struct tty	kl11[NKL11];
struct tty	dc11[NDC11];
struct lpcom
{	int	lp_cc;
	int	lp_cf;
	int	lp_cl;
	int	lp_flg;
	int	lp_linect;
	int	lp_spct;
	int	lp_bkct;
	char	*lp_lpaddr;
} lpcom[NOLPTS];

#ifdef RAW_BUFFER_POOL
struct buf	rawbufs[NRAWBUFS];
#endif
struct devtab rktab;
struct devtab rptab;

struct map
{	char	*m_size;
	char	*m_addr;
};
struct setup
{	char	*s_name;
	char	*intadd;
	unsigned extadd;
	unsigned s_size;
} setup[] {
	"proc",		&proc[0],	0,	sizeof proc,
	"text",		&text[0],	0,	sizeof text,
	"inode",	&inode[0],	0,	sizeof inode,
	"buf",		&buf[0],	0,	sizeof buf,
	"bfreelist",	&bfreelist,	0,	2,
	"file",		&file[0],	0,	sizeof file,
	"rawbufs",	&rawbufs[0],	0,	sizeof rawbufs,
	"cfree",	&cfree[0],	0,	sizeof cfree,
	"cfreelist",	&cfreelist,	0,	sizeof cfreelist,
	"dc11",		&dc11[0],	0,	sizeof dc11,
	"kl11",		&kl11[0],	0,	sizeof kl11,
	"lpcom",	&lpcom[0],	0,	sizeof lpcom,
	"swapmap",	&swapmap[0],	0,	sizeof swapmap-2,
	"coremap",	&coremap[0],	0,	sizeof coremap-2,
	"callout",	&callout[0],	0,	sizeof callout,
	"mount",	&mount[0],	0,	sizeof mount,
	"rktab",	&rktab,		0,	sizeof rktab,
	"rptab",	&rptab,		0,	sizeof rptab,
	0,		0,		0,	0
};

struct nl
{	char	nl_name[8];
	int	nl_type;
	int	nl_val;
} nl[30];

char *namelist	"/unix";
char *corefile	"/dev/kmem";
int	corefd;

char csw;
char ssw;
char psw;
char tsw;
char isw;
char fsw;
char lsw;
char msw;
char Csw;
char swset;
#define TSW(p)	if((swset == 0) || (swset && p))

main(argc, argv)
char **argv;
{
	register struct setup *s;
	while(--argc)
	{
		argv++;
		if(**argv != '-')
			break;
		while(**argv)
			switch(*++*argv)
			{
			case 'c': csw++; swset++; break;
			case 's': ssw++; swset++; break;
			case 'p': psw++; swset++; break;
			case 't': tsw++; swset++; break;
			case 'i': isw++; swset++; break;
			case 'f': fsw++; swset++; break;
			case 'l': lsw++; swset++; break;
			case 'C': Csw++; break;
			case 'm': msw++; swset++; break;
			case 'h':
				printf("c\tprint coremap\ns\tprint swapmap\n");
				printf("p\tprint proc\nt\tprint text\n");
				printf("i\tprint inode\nf\tprint file\n");
				printf("l\tprint callout\nh\tprint switches\n");
				printf("m\tprint mount\nC\tprint Clist\n");
				exit();
			}
	}
	if(argc)
	{	argc--;
		corefile = *argv;
	}
	if(argc)
	{	argv++;
		namelist = *argv;
	}
	if((corefd = open(corefile, 0)) < 0)
	{	printf("Cannot open core file\n");
		exit();
	}
	getvals();
	getconts();
	maps();
	TSW(psw) procpr();
	TSW(tsw) textpr();
	TSW(isw) inodepr();
	TSW(fsw) filepr();
	TSW(lsw) callpr();
	TSW(msw) mountpr();
	if(Csw) clistpr();
	if(Csw) lpclist();
	if(Csw) dclist();
	if(Csw) kllist();
}


/*
 *	get values from namelist on /unix file
 */
getvals()
{	register struct nl *n;
	register struct setup *s;

	n = &nl[0];
	for(s = &setup[0]; s->s_name; s++)
	{	n->nl_name[0] = '_';
		copy7(s->s_name, &n->nl_name[1]);
		n++;
	}
	nlist(namelist, &nl[0]);
	n = &nl[0];
	for(s = &setup[0]; s->s_name; s++)
	{	if(n->nl_type == -1)
			printf("No name entry in %s for %s\n", namelist, s->s_name);
		s->extadd = n->nl_val;
		n++;
	}
}

copy7(s, d)
register char *s, *d;
{	register i;
	for(i = 0; i < 7; i++)
		if(!(*d++ = *s++)) return;
}
/*
 * get contents from memory into
 * internal areas
 */

getconts()
{	register struct setup *s;
	nice(-20);
	for(s = &setup[0]; s->s_name; s++)
	{	if(s->extadd == -1) continue;
		seek(corefd, s->extadd, 0);
		if(read(corefd, s->intadd, s->s_size) != s->s_size)
		{	printf("Cannot read area for %s\n", s->s_name);
		}
	}
	nice(0);
}

struct setup *find(add)
unsigned add;
{	register struct setup *s;
	for(s = &setup[0]; s->s_name; s++)
	{	if(s->intadd == add)
		{	if(s->extadd == -1) return(-1);
			else return(s);
		}
	}
	return(-1);
}

/*
 * print out swap and core map usgae
 */
maps()
{	register struct setup *s;
	if((s = find(&coremap[0])) != -1)
	{
		TSW(csw) maprint(s);
	}
	if((s = find(&swapmap[0])) != -1)
	{	TSW(ssw) maprint(s);
	}
}
maprint(s)
register struct setup *s;
{	register struct map *m;
	char *endpt;
	register ct, tct;

	ct = 0;
	tct = 0;
	endpt = s->intadd + s->s_size;
	for(m = s->intadd; m < endpt; m++)
	{	tct++;
		if(m->m_size) ct++;
	}
	printf("%s: %4d used out of %4d - %4d free bytes\n", s->s_name, ct, tct, (tct - ct)*sizeof *m);
}

procpr()
{	register struct setup *s;
	register struct proc *p;
	int tct = 0, ct = 0;
	char *endpt;
	if((s = find(&proc[0])) == -1) return;
	endpt = s->intadd + s->s_size;
	for(p = s->intadd; p < endpt; p++)
	{	tct++;
		if(p->p_stat) ct++;
	}
	printf("proc:    %4d used out of %4d - %4d free bytes\n", ct, tct, (tct -ct)*sizeof *p);
}

textpr()
{	register struct setup *s;
	register struct text *x;
	char *endpt;
	int tct = 0, ct = 0;
	if((s = find(&text[0])) == -1) return;
	endpt = s->intadd + s->s_size;
	for(x = &text[0]; x < endpt; x++)
	{	tct++;
		if(x->x_iptr) ct++;
	}
	printf("text:    %4d used out of %4d - %4d free bytes\n", ct, tct, (tct -ct) *sizeof *x);
}

inodepr()
{	register struct setup *s;
	register struct inode *ip;
	char *endpt;
	int tct = 0, ct = 0;
	if((s = find(&inode[0])) == -1) return;
	endpt = s->intadd + s->s_size;
	for(ip = &inode[0]; ip < endpt; ip++)
	{	tct++;
		if(ip->i_count) ct++;
	}
	printf("inode:   %4d used out of %4d - %4d free bytes\n", ct, tct, (tct -ct)*sizeof *ip);
}
filepr()
{	register struct setup *s;
	register struct file *f;
	char *endpt;
	int tct = 0, ct = 0;
	if((s = find(&file[0])) == -1) return;
	endpt = s->intadd + s->s_size;
	for(f = &file[0]; f < endpt; f++)
	{	tct++;
		if(f->f_count) ct++;
	}
	printf("file:    %4d used out of %4d - %4d free bytes\n", ct, tct, (tct - ct)* sizeof *f);
}

callpr()
{	register struct setup *s;
	register struct callo *c;
	int tct = 0, ct = 0;
	char *endpt;
	if((s = find(&callout[0])) == -1)return;
	endpt = s->intadd + s->s_size;
	for(c = &callout[0]; c < endpt; c++)
	{	tct++;
		if(c->c_func) ct++;
	}
	printf("callout: %4d used out of %4d - %4d free bytes\n", ct, tct, (tct - ct) * sizeof *c);
}

mountpr()
{	register struct setup *s;
	register struct mount *m;
	char *endpt;
	int tct = 0, ct = 0;
	if((s = find(&mount[0])) == -1) return;
	endpt = s->intadd+s->s_size;
	for(m = &mount[0]; m < endpt; m++)
	{	tct++;
		if(m->m_bufp) ct++;
	}
	printf("mount:   %4d used out of %4d - %4d free bytes\n", ct, tct, (tct-ct)*sizeof *m);
}

unsigned exttoint(v, s)
register unsigned v;
register struct setup *s;
{	return((v - s->extadd) + s->intadd);	}

clistct(cb)
register struct cblock *cb;
{	register struct setup *s;
	register ct = 0;

	if((s = find(&cfree[0])) == -1) return(0);
	cb = exttoint(cb, s);
	while(cb)
	{	ct++;
		if(cb->c_next == 0)
			cb = 0;
		else
			cb = exttoint(cb->c_next, s);
	}
	return(ct);
}

clistpr()
{
	register struct setup *s;
	register tct = 0, ct  = 0;

	if((s = find(&cfree[0])) == -1) return;
	if(find(&cfreelist) == -1) return;
	ct = clistct(&cfreelist[0]);
	tct = (sizeof cfree) / (sizeof *cfreelist);
	printf("Clist:   %4d free out of %4d - %4d free bytes\n", ct, tct, ct*sizeof *cfreelist);
}

lpclist()
{	register struct setup *s;
	register struct lpcom *l;
	register i;

	if((s = find(&lpcom[0])) == -1) return;
	if(find(&cfree[0]) == -1) return;

	for(i = 0; i < NOLPTS; i++)
	{	l = &lpcom[0];
		if(l->lp_cc)
			printf("\tlpr%c:    %4d used\n", i+'0', clistct(l->lp_cf&~017));
	}
}
dclist()
{	register struct setup *s;
	register struct tty *t;
	int ct = 0;
	register i;

	if(( s = find(&dc11[0])) == -1) return;
	if(find(&cfree[0]) == -1) return;
	for(i = 0; i < NDC11; i++)
	{	t = &dc11[i];
		ct = 0;
		if(t->t_inq.c_cc) ct = clistct(t->t_inq.c_cf&~017);
		if(t->t_outq.c_cc) ct =+ clistct(t->t_outq.c_cf&~017);
		if(ct)
		printf("\tdc11 %2d:   %4d used\n", t->t_dev, ct);
	}
}
kllist()
{	register struct setup *s;
	register struct tty *t;
	int ct = 0;
	register i;

	if(( s = find(&kl11[0])) == -1) return;
	if(find(&cfree[0]) == -1) return;
	for(i = 0; i < NKL11; i++)
	{	t = &kl11[i];
		ct = 0;
		if(t->t_inq.c_cc) ct = clistct(t->t_inq.c_cf&~017);
		if(t->t_outq.c_cc) ct =+ clistct(t->t_outq.c_cf&~017);
		if(ct)
		printf("\tkl11 %2d:   %4d used\n", t->t_dev, ct);
	}
}
