PWB1/sys/source/s8/check.c

Compare this file to the similar file:
Show the results in this format:

#

#include	"ino.h"
#include	"filsys.h"
#define	NINODE 16
#define SIZE 15
#define	NBLK 8
#define MAXERR 8
int	bufa;
int	rootflg;
int	badfree;
int	sflg;
int	lfdes;
int	lfptr;
int	ckfile;
struct inode inode[NINODE*NBLK];
struct filsys sblock;
char	bitcnt[]
{
	4,3,3,2,3,2,2,1,
	3,2,2,1,2,1,1,0,
};
int	ndlist;
int	dlist[100];
char	*great;
char	list[512];
char	*dargv[SIZE];
char	*lptr;
int	nblist;
int	blist[100];
char	*bmap -1;
int	bmapsize;
int	nifiles;
int	fi;
int	nfile;
int	nspcl;
int	nlarg;
int	nindir;
int	ndir;
int	nused;
int	hiwat;
int	nfree;
int	ino;
int	ndup;
int	nmiss;
int	nnf	100;
int	inoerrs;
int	errs;

struct {
	char	icnt[2];
} *icnt;
struct { char *ptr; };
char	*ucnt;

struct	fname
{
	int	inum;
	int	nptr;
	int	pnum;
} *dn, *edn;

int	ldivr;
int	fout;

main(argc, argv)
char **argv;
{
	char *arg;
	register *p;
	register int nread;
	int	buf[19];

	argv[argc] = 0;
	if(argc == 1) {
		if((ckfile = open("/etc/checklist",0)) <0) {
			fprintf("Cannot open checklist\n");
			exit(1);
		}
		nread = sizeof list;
		fstat(ckfile,&buf[0]);
		if(buf[5] > nread) {
			fprintf("ERROR- Checklist to large\n");
			exit(1);
		}
		if((nread = read(ckfile,&list[0],sizeof list)) < 0) {
			fprintf("read error on checklist\n");
			exit(1);
		}
		lptr = list;
		argv = dargv;
		*argv++ = 0;
		*argv = lptr;
		while(nread-- > 0) {
			if(*lptr == '\n') {
				*lptr = '\0';
				*++argv = ++lptr;
				if(argc == SIZE) {
					fprintf("ERROR- To many args in checklist\n");
					exit(1);
				}
				argc++;
				continue;
			}
			lptr++;
		}
		dargv[argc] = 0;
		argv = dargv;
		close(ckfile);
	}

	if(argc>1 && *argv[1] == '-') {
		argc--;
		argv++;
		arg = *argv;
		while(*++arg)
		switch(*arg) {

		case 's':
			sflg++;
			continue;

		case 'i':
			dlist[ndlist++] = number(argv[1]);
			argc--;
			argv++;
			continue;

		case 'b':
			blist[nblist++] = number(argv[1]);
			argc--;
			argv++;
			continue;

		case 'g':
			great = number(argv[1]);
			argc--;
			argv++;
			continue;


		default:
			fprintf("bad option %c\n",arg[-1]);
			continue;
		}
	}
	fout = dup(1);
	argv++;
	argc--;
	fprintf("%s:\n", argv[0]);
	if(stat("/",&buf[0]) || stat(argv[0],&buf[1])) {
		fprintf("stat error\n");
	}else {
		if(buf[6+1] == buf[0]) {
			rootflg++;
		}
		check(argv[0]);
	}
	flush();
	close(fout);
	fout = 1;
	if(argc > 1) {
		execv("/etc/check",argv);
	}
}

check(file)
char *file;
{
	struct inode buf[16];
	register i, j;
	struct fname *dnp;

	fi = open(file, 0);
	if(fi < 0) {
		fprintf("cannot open %s\n", file);
		return;
	}
	sync();
	bread(1, &sblock, 512);
	if((sblock.s_isize+2) > sblock.s_fsize.ptr ||
	sblock.s_isize <0 || sblock.s_isize >4096) {
		fprintf("size check: fsize %l, isize %l\n",
		sblock.s_fsize,sblock.s_isize);
		return;
	}
	bmapsize = ((sblock.s_fsize>>3)&017777)+1;
	nifiles = sblock.s_isize*16;
	if((bmap = sbrk(bmapsize)) <0 ||
	   (icnt = sbrk(nifiles)) <0) {
		fprintf("Not enough memory\n");
		return;
	}
	for(i=2;ino<nifiles;i=+NBLK) {
		bread(i, inode, sizeof inode);
		for(j=0; j<NINODE*NBLK && ino < nifiles; j++) {
			ino++;
			pass1(&inode[j]);
		}
	}
	ino = 0;
	sync();
	bread(1, &sblock, 512);
	if(sflg) {
		close(fi);
		fi = open(file, 1);
		if(fi < 0) {
			fprintf("cannot write %s\n", file);
			return;
		}
		sblock.s_nfree = 0;
		sblock.s_tfree = 0;
		sblock.s_ninode = 0;
		sblock.s_flock = 0;
		sblock.s_ilock = 0;
		sblock.s_fmod = 0;
		free(0);
		for(i=sblock.s_fsize-1; i>=sblock.s_isize+2; i--) {
			ndup = 0;
			chk(i, "URK", 0);
			if(ndup == 0)
				free(i);
		}
		bwrite(1, &sblock);
		close(fi);
		sync();
		return;
	}
	while(i = alloc()) {
		if(chk(i, "free", 0))
			break;
		nfree++;
	}
	if(ndup)
		printf("%l dups in free\n", ndup);
	nmiss = sblock.s_fsize - sblock.s_isize - 2;
	for(i=0; i<bmapsize; i++) {
		j = bmap[i];
		nmiss =+ bitcnt[j&017];
		nmiss =+ bitcnt[(j>>4)&017];
	}
	nmiss =+ (8192-bmapsize)*8;
	if(nmiss)
		printf("%l missing\n", nmiss);
	for(i=0; i<sblock.s_isize*16; i++) {
		j = icnt->icnt[i] & 0377;
		if(j!=0 && j!=0200)
			printf("%6l %3o\n", i+1, j);
	}
	printf("spcl  %6l\n", nspcl);
	printf("files %6l\n", nfile);
	printf("large %6l\n", nlarg);
	printf("direc %6l\n", ndir);
	printf("indir %6l\n", nindir);
	printf("used  %6l\n", nused);
	printf("last  %6l\n", hiwat);
	printf("free  %6l\n", nfree);
	close(fi);
}


pass1(ip)
struct inode *ip;
{
	int buf[256];
	register i, j, df;
	int k;

	if((ip->i_mode&IALLOC) == 0){
		if(ip->i_mode != 0) fprintf("INODE - BAD FORMAT : inode =%o\n",
			ino);
		return;
	}
	icnt->icnt[ino-1] =+ 0100;
	if(ip->i_nlink)
		icnt->icnt[ino-1] =+ 0100 + ip->i_nlink;
	if((ip->i_mode&IFCHR&IFBLK) != 0) {
		nspcl++;
		return;
	}
	inoerrs = 0;
	df = 0;
	if((ip->i_mode&IFMT) == IFDIR) {
		df = (ip->i_size1>>4)&017777;
		ndir++;
		if(ip->i_size0) {
			fprintf("directory bigger than 2^16: inode=%l\n",ino);
		}
	}
	nfile++;
	if((ip->i_mode&ILARG) != 0) {
		nlarg++;
		for(i=0; i<8; i++)
		if(ip->i_addr[i] != 0) {
			nindir++;
			if(chk(ip->i_addr[i], "indirect", 0))
				continue;
			bread(ip->i_addr[i], buf, 512);
			for(j=0; j<256; j++) {
				if(buf[j] != 0)
					chk(buf[j], "data (large)", df);
				if (df > 0) df =- 32;
			}
		}
	}else {
		for(i=0; i<8; i++) {
			if(ip->i_addr[i] != 0)
				chk(ip->i_addr[i], "data (small)", df);
			df =- 32;
		}
	}
	if(inoerrs > MAXERR)
		fprintf("excessive errors: inode= %l\n",ino);
}

chk(ii, s, df)
char *ii;
{
	register char *i;
	register n, j;
	int b;
	int buf[256];
	struct {
		int	ino;
		char	name[14];
	};

	i = ii;
	for(j=0; j<nblist; j++)
		if(i == blist[j])
			fprintf("%l blk: inode=%l(%s)\n", i, ino, s);
	if(great && i >= great && i)
		fprintf("%l geq; inode=%l(%s)\n", i, ino, s);
	if(ino) {
		nused++;
		if(i > hiwat)
			hiwat = i;
	}
	if(i<sblock.s_isize+2 || i>=sblock.s_fsize) {
		efprintf("%l bad; inode=%l(%s)\n", i, ino, s);
		return(1);
	}
	n = ldiv(0, i, 8);
	j = (1<<ldivr);
	if(bmap[n] & j) {
		if(ino == 0) {
			ndup++;
			return(0);
		}
		efprintf("%l dup; inode=%l(%s)\n", i, ino, s);
		return(1);
	}
	bmap[n] =| j;
	if(df>0) {
		bread(i, buf, 512);
		for(n=0; n<256; n=+8) {
			if(df <= 0)
				break;
			df--;
			if((b=buf[n]) == 0)
				continue;
			for(j=0; j<ndlist; j++)
				if(b == dlist[j])
				fprintf("%l ino: inode=%l(%s) \"%.16s\"\n",
				  b, ino, s, buf+n+1);
			if(b<1 || b> nifiles) {
				efprintf("%l din: inode=%l(%s)\n", i, ino, s);
				continue;
			}
			icnt->icnt[b-1]--;
		}
	}
	return(0);
}

alloc()
{
	register b, i;
	int buf[256];

	i = --sblock.s_nfree;
	if(i<0 || i>=100) {
		badfree++;
		fprintf("bad freeblock\n");
		return(0);
	}
	b = sblock.s_free[i];
	if(b == 0)
		return(0);
	if(sblock.s_nfree <= 0) {
		bread(b, buf, 512);
		sblock.s_nfree = buf[0];
		for(i=0; i<100; i++)
			sblock.s_free[i] = buf[i+1];
	}
	return(b);
}

bread(bno, buf, cnt)
int	*buf;
{

	seek(fi, bno, 3);
	if(read(fi, buf, cnt) != cnt) {
		fprintf("read error %d\n", bno);
		exit(1);
	}
}

free(in)
{
	int i;
	int buf[256];

	if(sblock.s_nfree >= 100) {
		buf[0] = sblock.s_nfree;
		for(i=0; i<100; i++)
			buf[i+1] = sblock.s_free[i];
		sblock.s_nfree = 0;
		bwrite(in, buf);
	}
	sblock.s_free[sblock.s_nfree++] = in;
	if(in) sblock.s_tfree++;
}

bwrite(bno, buf)
{

	seek(fi, bno, 3);
	if(write(fi, buf, 512) != 512) {
		fprintf("write error %d\n", bno);
		exit(1);
	}
}

number(s)
char *s;
{
	int n, c;

	n = 0;
	while(c = *s++) {
		if(c<'0' || c>'9')
			continue;
		n = n*10+c-'0';
	}
	return(n);
}

fprintf(a, b, c, d, e)
{
	printf(a, b, c, d, e);
	flush();
}

efprintf(a, b, c, d, e)
{
	errs++;
	if(inoerrs >= MAXERR)
		return;
	inoerrs++;
	printf(a, b, c, d, e);
	flush();
}