/*
 * tron: check routines; checkdir() and chki()
 */
#include	"tron.h"

checkdir(dp)
register struct direc *dp;
{
	register struct direct *d1, *d2;
	struct stat statb;
	short flag, fd, r, *ip;
	char *f, *fp;
	static char dbuf[512], fname[64];
	long tv[2];

	exflg = dp->d_timeo;
	nex = getexc(makenm(dp->d_data, ".exc"));
	flag = getstats(f = makenm(dp->d_data, ".ino"));
	exchksum = 0;
	strcpy(fp = fname, dp->d_namep);
	if((fd = open(fp, 0)) == -1){
		fprintf(stdout, "*TRON: Directory open error %s\n", fp);
		return(1);
	}
	if((fo = creat(f, 0600)) == -1){
		fprintf(stdout, "*TRON: Can't creat new %s\n", f);
		close(fd);
		return(1);
	}
	po = obuf;
	while(*fp)fp++;
	*fp++ = '/';
	while(r = read(fd, dbuf, 512)){
		r &= ~1;
		for(d1 = dbuf, d2 = &dbuf[r]; d1 < d2; d1++){
			if(d1->d_ino == 0)continue;
			strcpy(fp, d1->d_name);
			fp[14] = 0;
			chki(fname, d1->d_name, flag);
		}
	}
	close(fd);
	flusho();
	close(fo);
	if(stat(f, &statb) == -1){
		fprintf(stdout, "*TRON: Can't restat %s for close\n", f);
		return(2);
	}
	tv[0] = statb.st_size;
	tv[1] = exchksum;
	utime(f, tv);
	wasdeleted(dp->d_namep);
	return(0);
}

chki(f, base, flag)
char *f, *base;
short flag;
{
	struct stat statb;
	register struct stat *ip;
	register short i;
	register struct sstat *sp;

	if(stat(f, &statb) == -1){
		fprintf(stdout, "*TRON: Can't stat %s\n", f);
		return;
	}
	if(exflg & CKSUM)
		statb.st_chksum = chks(f, statb.st_time);
	addi(&statb, base);
	any = 0;
	if(flag){
		i = statb.st_inumber;
		for(sp = &stbuf[nent-1]; sp >= stbuf; sp--){
			if(sp->ss_name[0] == 0)
				continue;
			if(strncmp(base, sp, DIRSIZ))
				continue;
			sp->ss_name[0] = 0;
			if(inlog(base) || isexc(base))
				return;
			ip = &sp->ss_stat;
			if(ip->st_inumber != i)
				pr("inode number");
			if(ip->st_mode != statb.st_mode)
				pr("mode");
			if(ip->st_nlinks != statb.st_nlinks)
				pr("link count");
			if(ip->st_uid != statb.st_uid)
				pr("uid");
			if(ip->st_gid != statb.st_gid)
				pr("gid");
			if(ip->st_size != statb.st_size)
				pr("size");
			if((exflg & ATIME) && ip->st_time[0] != statb.st_time[0])
				pr("access time");
			if((exflg & MTIME) && ip->st_time[1] != statb.st_time[1])
				pr("modified time");
			if(ip->st_time[2] != statb.st_time[2])
				pr((exflg & CKSUM) ? "checksum" : "C-time");
			if(any)
				fprintf(stdout, " of %s %s changed\n", f,
					any == 1 ? "has" : "have");
			return;
		}
		if(!inlog(base) && !isexc(base))
			fprintf(stdout, "*TRON: New file appeared: %s\n", f);
	}
}

